diff options
author | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-10 21:46:48 +0000 |
---|---|---|
committer | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-10 21:46:48 +0000 |
commit | ce57ab760f69de6db452def7ffbf5b114a2d8694 (patch) | |
tree | ea38c56431c5d4528fb54254c3f8e50f517bede3 /libjava/classpath/java | |
parent | 50996fe55769882de3f410896032c887f0ff0d04 (diff) | |
download | gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.tar.gz |
Imported GNU Classpath 0.90
* scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore.
* gnu/classpath/jdwp/VMFrame.java (SIZE): New constant.
* java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5.
* java/lang/Math.java: New override file.
* java/lang/Character.java: Merged from Classpath.
(start, end): Now 'int's.
(canonicalName): New field.
(CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants.
(UnicodeBlock): Added argument.
(of): New overload.
(forName): New method.
Updated unicode blocks.
(sets): Updated.
* sources.am: Regenerated.
* Makefile.in: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111942 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/java')
156 files changed, 10349 insertions, 6127 deletions
diff --git a/libjava/classpath/java/awt/AWTEvent.java b/libjava/classpath/java/awt/AWTEvent.java index ad9533f9c26..d10433cb3c3 100644 --- a/libjava/classpath/java/awt/AWTEvent.java +++ b/libjava/classpath/java/awt/AWTEvent.java @@ -39,6 +39,19 @@ exception statement from your version. */ package java.awt; +import java.awt.event.ActionEvent; +import java.awt.event.AdjustmentEvent; +import java.awt.event.ComponentEvent; +import java.awt.event.ContainerEvent; +import java.awt.event.FocusEvent; +import java.awt.event.InputMethodEvent; +import java.awt.event.InvocationEvent; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.PaintEvent; +import java.awt.event.TextEvent; +import java.awt.event.WindowEvent; import java.util.EventObject; /** @@ -275,4 +288,94 @@ public abstract class AWTEvent extends EventObject { return consumed; } + + /** + * Converts an event id to the appropriate event mask. + * + * @param id the event id + * + * @return the event mask for the specified id + */ + static long eventIdToMask(int id) + { + long mask = 0; + switch (id) + { + case ActionEvent.ACTION_PERFORMED: + mask = ACTION_EVENT_MASK; + break; + case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: + mask = ADJUSTMENT_EVENT_MASK; + break; + case ComponentEvent.COMPONENT_MOVED: + case ComponentEvent.COMPONENT_RESIZED: + case ComponentEvent.COMPONENT_SHOWN: + case ComponentEvent.COMPONENT_HIDDEN: + mask = COMPONENT_EVENT_MASK; + break; + case ContainerEvent.COMPONENT_ADDED: + case ContainerEvent.COMPONENT_REMOVED: + mask = CONTAINER_EVENT_MASK; + break; + case FocusEvent.FOCUS_GAINED: + case FocusEvent.FOCUS_LOST: + mask = FOCUS_EVENT_MASK; + break; + case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: + case InputMethodEvent.CARET_POSITION_CHANGED: + mask = INPUT_METHOD_EVENT_MASK; + break; + case InvocationEvent.INVOCATION_DEFAULT: + mask = INVOCATION_EVENT_MASK; + break; + case ItemEvent.ITEM_STATE_CHANGED: + mask = ITEM_EVENT_MASK; + break; + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + mask = KEY_EVENT_MASK; + break; + case MouseEvent.MOUSE_CLICKED: + case MouseEvent.MOUSE_PRESSED: + case MouseEvent.MOUSE_RELEASED: + mask = MOUSE_EVENT_MASK; + break; + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_ENTERED: + case MouseEvent.MOUSE_EXITED: + case MouseEvent.MOUSE_DRAGGED: + mask = MOUSE_MOTION_EVENT_MASK; + break; + case MouseEvent.MOUSE_WHEEL: + mask = MOUSE_WHEEL_EVENT_MASK; + break; + case PaintEvent.PAINT: + case PaintEvent.UPDATE: + mask = PAINT_EVENT_MASK; + break; + case TextEvent.TEXT_VALUE_CHANGED: + mask = TEXT_EVENT_MASK; + break; + case WindowEvent.WINDOW_OPENED: + case WindowEvent.WINDOW_CLOSING: + case WindowEvent.WINDOW_CLOSED: + case WindowEvent.WINDOW_ICONIFIED: + case WindowEvent.WINDOW_DEICONIFIED: + case WindowEvent.WINDOW_ACTIVATED: + case WindowEvent.WINDOW_DEACTIVATED: + mask = WINDOW_EVENT_MASK; + break; + case WindowEvent.WINDOW_GAINED_FOCUS: + case WindowEvent.WINDOW_LOST_FOCUS: + mask = WINDOW_FOCUS_EVENT_MASK; + break; + case WindowEvent.WINDOW_STATE_CHANGED: + mask = WINDOW_STATE_EVENT_MASK; + break; + default: + mask = 0; + } + return mask; + } } // class AWTEvent diff --git a/libjava/classpath/java/awt/BasicStroke.java b/libjava/classpath/java/awt/BasicStroke.java index bb008e4c791..4eece75c995 100644 --- a/libjava/classpath/java/awt/BasicStroke.java +++ b/libjava/classpath/java/awt/BasicStroke.java @@ -1,5 +1,5 @@ /* BasicStroke.java -- - Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,38 +41,89 @@ package java.awt; import java.util.Arrays; /** - * STUB CLASS ONLY + * A general purpose {@link Stroke} implementation that can represent a wide + * variety of line styles for use with subclasses of {@link Graphics2D}. + * <p> + * The line cap and join styles can be set using the options illustrated + * here: + * <p> + * <img src="doc-files/capjoin.png" width="350" height="180" + * alt="Illustration of line cap and join styles" /> + * <p> + * A dash array can be used to specify lines with alternating opaque and + * transparent sections. */ public class BasicStroke implements Stroke { + /** + * Indicates a mitered line join style. See the class overview for an + * illustration. + */ public static final int JOIN_MITER = 0; + + /** + * Indicates a rounded line join style. See the class overview for an + * illustration. + */ public static final int JOIN_ROUND = 1; + + /** + * Indicates a bevelled line join style. See the class overview for an + * illustration. + */ public static final int JOIN_BEVEL = 2; + /** + * Indicates a flat line cap style. See the class overview for an + * illustration. + */ public static final int CAP_BUTT = 0; + + /** + * Indicates a rounded line cap style. See the class overview for an + * illustration. + */ public static final int CAP_ROUND = 1; + + /** + * Indicates a square line cap style. See the class overview for an + * illustration. + */ public static final int CAP_SQUARE = 2; + /** The stroke width. */ private final float width; + + /** The line cap style. */ private final int cap; + + /** The line join style. */ private final int join; + + /** The miter limit. */ private final float limit; + + /** The dash array. */ private final float[] dash; + + /** The dash phase. */ private final float phase; /** - * Creates a basic stroke. + * Creates a new <code>BasicStroke</code> instance with the given attributes. * - * @param width May not be negative . - * @param cap May be either CAP_BUTT, CAP_ROUND or CAP_SQUARE. - * @param join May be either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER. - * @param miterlimit the limit to trim the miter join. The miterlimit must be + * @param width the line width (>= 0.0f). + * @param cap the line cap style (one of {@link #CAP_BUTT}, + * {@link #CAP_ROUND} or {@link #CAP_SQUARE}). + * @param join the line join style (one of {@link #JOIN_ROUND}, + * {@link #JOIN_BEVEL}, or {@link #JOIN_MITER}). + * @param miterlimit the limit to trim the miter join. The miterlimit must be * greater than or equal to 1.0f. * @param dash The array representing the dashing pattern. There must be at * least one non-zero entry. * @param dashPhase is negative and dash is not null. * - * @exception IllegalArgumentException If one input parameter doesn't meet + * @throws IllegalArgumentException If one input parameter doesn't meet * its needs. */ public BasicStroke(float width, int cap, int join, float miterlimit, @@ -122,15 +173,17 @@ public class BasicStroke implements Stroke } /** - * Creates a basic stroke. + * Creates a new <code>BasicStroke</code> instance with the given attributes. * - * @param width The width of the BasicStroke. May not be negative . - * @param cap May be either CAP_BUTT, CAP_ROUND or CAP_SQUARE. - * @param join May be either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER. + * @param width the line width (>= 0.0f). + * @param cap the line cap style (one of {@link #CAP_BUTT}, + * {@link #CAP_ROUND} or {@link #CAP_SQUARE}). + * @param join the line join style (one of {@link #JOIN_ROUND}, + * {@link #JOIN_BEVEL}, or {@link #JOIN_MITER}). * @param miterlimit the limit to trim the miter join. The miterlimit must be * greater than or equal to 1.0f. * - * @exception IllegalArgumentException If one input parameter doesn't meet + * @throws IllegalArgumentException If one input parameter doesn't meet * its needs. */ public BasicStroke(float width, int cap, int join, float miterlimit) @@ -139,15 +192,17 @@ public class BasicStroke implements Stroke } /** - * Creates a basic stroke. + * Creates a new <code>BasicStroke</code> instance with the given attributes. + * The miter limit defaults to <code>10.0</code>. * - * @param width The width of the BasicStroke. May not be nehative. - * @param cap May be either CAP_BUTT, CAP_ROUND or CAP_SQUARE. - * @param join May be either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER. + * @param width the line width (>= 0.0f). + * @param cap the line cap style (one of {@link #CAP_BUTT}, + * {@link #CAP_ROUND} or {@link #CAP_SQUARE}). + * @param join the line join style (one of {@link #JOIN_ROUND}, + * {@link #JOIN_BEVEL}, or {@link #JOIN_MITER}). * - * @exception IllegalArgumentException If one input parameter doesn't meet + * @throws IllegalArgumentException If one input parameter doesn't meet * its needs. - * @exception IllegalArgumentException FIXME */ public BasicStroke(float width, int cap, int join) { @@ -155,11 +210,17 @@ public class BasicStroke implements Stroke } /** - * Creates a basic stroke. - * - * @param width The width of the BasicStroke. + * Creates a new <code>BasicStroke</code> instance with the given line + * width. The default values are: + * <ul> + * <li>line cap style: {@link #CAP_SQUARE};</li> + * <li>line join style: {@link #JOIN_MITER};</li> + * <li>miter limit: <code>10.0f</code>. + * </ul> + * + * @param width the line width (>= 0.0f). * - * @exception IllegalArgumentException If width is negative. + * @throws IllegalArgumentException If <code>width</code> is negative. */ public BasicStroke(float width) { @@ -167,43 +228,92 @@ public class BasicStroke implements Stroke } /** - * Creates a basic stroke. + * Creates a new <code>BasicStroke</code> instance. The default values are: + * <ul> + * <li>line width: <code>1.0f</code>;</li> + * <li>line cap style: {@link #CAP_SQUARE};</li> + * <li>line join style: {@link #JOIN_MITER};</li> + * <li>miter limit: <code>10.0f</code>. + * </ul> */ public BasicStroke() { this(1, CAP_SQUARE, JOIN_MITER, 10, null, 0); } + /** + * Creates a shape representing the stroked outline of the given shape. + * THIS METHOD IS NOT YET IMPLEMENTED. + * + * @param s the shape. + */ public Shape createStrokedShape(Shape s) { + // FIXME: Implement this throw new Error("not implemented"); } + /** + * Returns the line width. + * + * @return The line width. + */ public float getLineWidth() { return width; } + /** + * Returns a code indicating the line cap style (one of {@link #CAP_BUTT}, + * {@link #CAP_ROUND}, {@link #CAP_SQUARE}). + * + * @return A code indicating the line cap style. + */ public int getEndCap() { return cap; } + /** + * Returns a code indicating the line join style (one of {@link #JOIN_BEVEL}, + * {@link #JOIN_MITER} or {@link #JOIN_ROUND}). + * + * @return A code indicating the line join style. + */ public int getLineJoin() { return join; } + /** + * Returns the miter limit. + * + * @return The miter limit. + */ public float getMiterLimit() { return limit; } + /** + * Returns the dash array, which defines the length of alternate opaque and + * transparent sections in lines drawn with this stroke. If + * <code>null</code>, a continuous line will be drawn. + * + * @return The dash array (possibly <code>null</code>). + */ public float[] getDashArray() { return dash; } + /** + * Returns the dash phase for the stroke. This is the offset from the start + * of a path at which the pattern defined by {@link #getDashArray()} is + * rendered. + * + * @return The dash phase. + */ public float getDashPhase() { return phase; @@ -215,6 +325,8 @@ public class BasicStroke implements Stroke * (converted to <code>int</code> first with * <code>Float.floatToIntBits()</code> if the value is a * <code>float</code>). + * + * @return The hash code. */ public int hashCode() { @@ -233,9 +345,18 @@ public class BasicStroke implements Stroke } /** - * Returns true if the given Object is an instance of BasicStroke - * and the width, cap, join, limit, dash array and phase are all - * equal. + * Compares this <code>BasicStroke</code> for equality with an arbitrary + * object. This method returns <code>true</code> if and only if: + * <ul> + * <li><code>o</code> is an instanceof <code>BasicStroke</code>;<li> + * <li>this object has the same width, line cap style, line join style, + * miter limit, dash array and dash phase as <code>o</code>.</li> + * </ul> + * + * @param o the object (<code>null</code> permitted). + * + * @return <code>true</code> if this stroke is equal to <code>o</code> and + * <code>false</code> otherwise. */ public boolean equals(Object o) { @@ -245,4 +366,4 @@ public class BasicStroke implements Stroke return width == s.width && cap == s.cap && join == s.join && limit == s.limit && Arrays.equals(dash, s.dash) && phase == s.phase; } -} // class BasicStroke +} diff --git a/libjava/classpath/java/awt/BorderLayout.java b/libjava/classpath/java/awt/BorderLayout.java index 7c8c582a96b..50061ec6771 100644 --- a/libjava/classpath/java/awt/BorderLayout.java +++ b/libjava/classpath/java/awt/BorderLayout.java @@ -460,27 +460,30 @@ public class BorderLayout implements LayoutManager2, java.io.Serializable } /** - * Lays out the specified container according to the constraints - * in this object. - * + * Lays out the specified container according to the constraints in this + * object. + * * @param target The container to lay out. */ public void layoutContainer(Container target) { - synchronized (target.getTreeLock ()) + synchronized (target.getTreeLock()) { Insets i = target.getInsets(); + int top = i.top; + int bottom = target.height - i.bottom; + int left = i.left; + int right = target.width - i.right; - ComponentOrientation orient = target.getComponentOrientation (); - boolean left_to_right = orient.isLeftToRight (); + boolean left_to_right = target.getComponentOrientation().isLeftToRight(); Component my_north = north; Component my_east = east; Component my_south = south; Component my_west = west; - // Note that we currently don't handle vertical layouts. Neither - // does JDK 1.3. + // Note that we currently don't handle vertical layouts. + // Neither does JDK 1.3. if (firstLine != null) my_north = firstLine; if (lastLine != null) @@ -500,65 +503,42 @@ public class BorderLayout implements LayoutManager2, java.io.Serializable my_west = lastItem; } - Dimension c = calcCompSize(center, PREF); - Dimension n = calcCompSize(my_north, PREF); - Dimension s = calcCompSize(my_south, PREF); - Dimension e = calcCompSize(my_east, PREF); - Dimension w = calcCompSize(my_west, PREF); - int targetWidth = target.getWidth(); - int targetHeight = target.getHeight(); - - /* - <-> hgap <-> hgap - +----------------------------+ } - |t | } i.top - | +----------------------+ | --- y1 } - | |n | | - | +----------------------+ | } vgap - | +---+ +----------+ +---+ | --- y2 } } - | |w | |c | |e | | } hh - | +---+ +----------+ +---+ | } vgap } - | +----------------------+ | --- y3 } - | |s | | - | +----------------------+ | } - | | } i.bottom - +----------------------------+ } - |x1 |x2 |x3 - <----------------------> - <--> ww <--> - i.left i.right - */ - - int x1 = i.left; - int x2 = x1 + w.width + (w.width == 0 ? 0 : hgap); - int x3; - if (targetWidth <= i.right + e.width) - x3 = x2 + w.width + (w.width == 0 ? 0 : hgap); - else - x3 = targetWidth - i.right - e.width; - int ww = targetWidth - i.right - i.left; - - int y1 = i.top; - int y2 = y1 + n.height + (n.height == 0 ? 0 : vgap); - int midh = Math.max(e.height, Math.max(w.height, c.height)); - int y3; - if (targetHeight <= i.bottom + s.height) - y3 = y2 + midh + vgap; - else - y3 = targetHeight - i.bottom - s.height; - int hh = y3-y2-(s.height == 0 ? 0 : vgap); - - setBounds(center, x2, y2, x3-x2-(w.width == 0 ? 0 : hgap), hh); - setBounds(my_north, x1, y1, ww, n.height); - setBounds(my_south, x1, y3, ww, s.height); - setBounds(my_west, x1, y2, w.width, hh); - setBounds(my_east, x3, y2, e.width, hh); + if (my_north != null) + { + Dimension n = calcCompSize(my_north, PREF); + my_north.setBounds(left, top, right - left, n.height); + top += n.height + vgap; + } + + if (my_south != null) + { + Dimension s = calcCompSize(my_south, PREF); + my_south.setBounds(left, bottom - s.height, right - left, s.height); + bottom -= s.height + vgap; + } + + if (my_east != null) + { + Dimension e = calcCompSize(my_east, PREF); + my_east.setBounds(right - e.width, top, e.width, bottom - top); + right -= e.width + hgap; + } + + if (my_west != null) + { + Dimension w = calcCompSize(my_west, PREF); + my_west.setBounds(left, top, w.width, bottom - top); + left += w.width + hgap; + } + + if (center != null) + center.setBounds(left, top, right - left, bottom - top); } } /** * Returns a string representation of this layout manager. - * + * * @return A string representation of this object. */ public String toString() @@ -566,20 +546,9 @@ public class BorderLayout implements LayoutManager2, java.io.Serializable return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]"; } - /** - * This is a convenience method to set the bounds on a component. - * If the indicated component is null, nothing is done. - */ - private void setBounds(Component comp, int x, int y, int w, int h) - { - if (comp == null) - return; - comp.setBounds(x, y, w, h); - } - private Dimension calcCompSize(Component comp, int what) { - if (comp == null || !comp.isVisible()) + if (comp == null || ! comp.isVisible()) return new Dimension(0, 0); if (what == MIN) return comp.getMinimumSize(); @@ -589,12 +558,12 @@ public class BorderLayout implements LayoutManager2, java.io.Serializable } /** - * This is a helper function used to compute the various sizes for - * this layout. + * This is a helper function used to compute the various sizes for this + * layout. */ private Dimension calcSize(Container target, int what) { - synchronized (target.getTreeLock ()) + synchronized (target.getTreeLock()) { Insets ins = target.getInsets(); diff --git a/libjava/classpath/java/awt/CardLayout.java b/libjava/classpath/java/awt/CardLayout.java index 8582c5f099b..8b3fea2ca23 100644 --- a/libjava/classpath/java/awt/CardLayout.java +++ b/libjava/classpath/java/awt/CardLayout.java @@ -117,7 +117,7 @@ public class CardLayout implements LayoutManager2, Serializable /** * Cause the first component in the container to be displayed. * - * @param parent The parent container + * @param parent The parent container, not <code>null</code>. */ public void first (Container parent) { @@ -181,7 +181,7 @@ public class CardLayout implements LayoutManager2, Serializable /** * Cause the last component in the container to be displayed. * - * @param parent The parent container + * @param parent The parent container, not <code>null</code>. */ public void last (Container parent) { @@ -247,7 +247,7 @@ public class CardLayout implements LayoutManager2, Serializable * this current card is the last one in the deck, the first * component is displayed. * - * @param parent The parent container + * @param parent The parent container, not <code>null</code>. */ public void next (Container parent) { @@ -271,7 +271,7 @@ public class CardLayout implements LayoutManager2, Serializable * If this current card is the first one in the deck, the last * component is displayed. * - * @param parent The parent container + * @param parent The parent container, not <code>null</code>. */ public void previous (Container parent) { @@ -321,13 +321,19 @@ public class CardLayout implements LayoutManager2, Serializable /** * Cause the named component to be shown. If the component name is - * unknown, this method does nothing. + * unknown or <code>null</code>, this method does nothing. * - * @param parent The parent container - * @param name The name of the component to show + * @param parent The parent container, not <code>null</code>. + * @param name The name of the component to show */ public void show (Container parent, String name) { + if (name == null) + return; + + if (parent.getLayout() != this) + throw new IllegalArgumentException("parent's layout is not this CardLayout"); + Object target = tab.get (name); if (target != null) { @@ -362,9 +368,15 @@ public class CardLayout implements LayoutManager2, Serializable * * @param parent The parent container * @param what The type of goto: FIRST, LAST, NEXT or PREV + * + * @throws IllegalArgumentException if parent has not this + * CardLayout set as its layout. */ private void gotoComponent (Container parent, int what) { + if (parent.getLayout() != this) + throw new IllegalArgumentException("parent's layout is not this CardLayout"); + synchronized (parent.getTreeLock ()) { int num = parent.ncomponents; diff --git a/libjava/classpath/java/awt/Checkbox.java b/libjava/classpath/java/awt/Checkbox.java index 93f60924723..eea443edf74 100644 --- a/libjava/classpath/java/awt/Checkbox.java +++ b/libjava/classpath/java/awt/Checkbox.java @@ -1,5 +1,6 @@ /* Checkbox.java -- An AWT checkbox widget - Copyright (C) 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -459,11 +460,14 @@ getState() public synchronized void setState(boolean state) { - this.state = state; - if (peer != null) + if (this.state != state) { - CheckboxPeer cp = (CheckboxPeer) peer; - cp.setState (state); + this.state = state; + if (peer != null) + { + CheckboxPeer cp = (CheckboxPeer) peer; + cp.setState (state); + } } } @@ -599,10 +603,15 @@ void dispatchEventImpl(AWTEvent e) { if (e.id <= ItemEvent.ITEM_LAST - && e.id >= ItemEvent.ITEM_FIRST - && (item_listeners != null - || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0)) - processEvent(e); + && e.id >= ItemEvent.ITEM_FIRST) + { + ItemEvent ie = (ItemEvent) e; + int itemState = ie.getStateChange(); + setState(itemState == ItemEvent.SELECTED ? true : false); + if (item_listeners != null + || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) + processEvent(e); + } else super.dispatchEventImpl(e); } diff --git a/libjava/classpath/java/awt/Choice.java b/libjava/classpath/java/awt/Choice.java index df93c5b0742..2e55d19b2d5 100644 --- a/libjava/classpath/java/awt/Choice.java +++ b/libjava/classpath/java/awt/Choice.java @@ -468,15 +468,16 @@ getSelectedIndex() public synchronized void select(int index) { - if ((index < 0) || (index > getItemCount())) + if ((index < 0) || (index >= getItemCount())) throw new IllegalArgumentException("Bad index: " + index); - this.selectedIndex = index; - if (peer != null) - { + if (pItems.size() > 0) { + selectedIndex = index; ChoicePeer cp = (ChoicePeer) peer; - cp.select (index); - } + if (cp != null) { + cp.select(index); + } + } } /*************************************************************************/ @@ -573,18 +574,6 @@ processItemEvent(ItemEvent event) item_listeners.itemStateChanged(event); } -void -dispatchEventImpl(AWTEvent e) -{ - if (e.id <= ItemEvent.ITEM_LAST - && e.id >= ItemEvent.ITEM_FIRST - && (item_listeners != null - || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0)) - processEvent(e); - else - super.dispatchEventImpl(e); -} - /*************************************************************************/ /** diff --git a/libjava/classpath/java/awt/Component.java b/libjava/classpath/java/awt/Component.java index bd22ea3c984..de01fc1145b 100644 --- a/libjava/classpath/java/awt/Component.java +++ b/libjava/classpath/java/awt/Component.java @@ -1,5 +1,6 @@ /* Component.java -- a graphics component - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006 + Free Software Foundation This file is part of GNU Classpath. @@ -40,6 +41,7 @@ package java.awt; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; +import java.awt.event.AdjustmentEvent; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; @@ -900,7 +902,7 @@ public abstract class Component // Avoid NullPointerExceptions by creating a local reference. ComponentPeer currentPeer=peer; if (currentPeer != null) - currentPeer.setVisible(true); + currentPeer.show(); // The JDK repaints the component before invalidating the parent. // So do we. @@ -1388,18 +1390,20 @@ public abstract class Component int oldy = this.y; int oldwidth = this.width; int oldheight = this.height; - - if (this.x == x && this.y == y - && this.width == width && this.height == height) + + if (this.x == x && this.y == y && this.width == width + && this.height == height) return; - invalidate (); + + invalidate(); + this.x = x; this.y = y; this.width = width; this.height = height; if (peer != null) peer.setBounds (x, y, width, height); - + // Erase old bounds and repaint new bounds for lightweights. if (isLightweight() && isShowing()) { @@ -1598,16 +1602,18 @@ public abstract class Component public Dimension preferredSize() { if (prefSize == null) - if (peer == null) - return new Dimension(width, height); - else - prefSize = peer.getPreferredSize(); + { + if (peer == null) + prefSize = minimumSize(); + else + prefSize = peer.getPreferredSize(); + } return prefSize; } /** * Returns the component's minimum size. - * + * * @return the component's minimum size * @see #getPreferredSize() * @see LayoutManager @@ -1882,8 +1888,7 @@ public abstract class Component */ public void repaint() { - if (isShowing()) - repaint(0, 0, 0, width, height); + repaint(0, 0, 0, width, height); } /** @@ -1897,8 +1902,7 @@ public abstract class Component */ public void repaint(long tm) { - if (isShowing()) - repaint(tm, 0, 0, width, height); + repaint(tm, 0, 0, width, height); } /** @@ -1915,8 +1919,7 @@ public abstract class Component */ public void repaint(int x, int y, int w, int h) { - if (isShowing()) - repaint(0, x, y, w, h); + repaint(0, x, y, w, h); } /** @@ -2308,6 +2311,10 @@ public abstract class Component */ public final void dispatchEvent(AWTEvent e) { + Event oldEvent = translateEvent(e); + if (oldEvent != null) + postEvent (oldEvent); + // Some subclasses in the AWT package need to override this behavior, // hence the use of dispatchEventImpl(). dispatchEventImpl(e); @@ -3419,10 +3426,11 @@ public abstract class Component } /** - * Called to inform this component it has been added to a container. - * A native peer - if any - is created at this time. This method is - * called automatically by the AWT system and should not be called by - * user level code. + * Called when the parent of this Component is made visible or when + * the Component is added to an already visible Container and needs + * to be shown. A native peer - if any - is created at this + * time. This method is called automatically by the AWT system and + * should not be called by user level code. * * @see #isDisplayable() * @see #removeNotify() @@ -3431,6 +3439,8 @@ public abstract class Component { if (peer == null) peer = getToolkit().createComponent(this); + else if (parent != null && parent.isLightweight()) + new HeavyweightInLightweightListener(parent); /* Now that all the children has gotten their peers, we should have the event mask needed for this component and its lightweight subcomponents. */ @@ -4481,6 +4491,109 @@ p * <li>the set of backward traversal keys } /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + * + * @since 1.5 + */ + public void firePropertyChange(String propertyName, byte oldValue, + byte newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, new Byte(oldValue), + new Byte(newValue)); + } + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + * + * @since 1.5 + */ + public void firePropertyChange(String propertyName, char oldValue, + char newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, new Character(oldValue), + new Character(newValue)); + } + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + * + * @since 1.5 + */ + public void firePropertyChange(String propertyName, short oldValue, + short newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, new Short(oldValue), + new Short(newValue)); + } + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + * + * @since 1.5 + */ + public void firePropertyChange(String propertyName, long oldValue, + long newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, new Long(oldValue), + new Long(newValue)); + } + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + * + * @since 1.5 + */ + public void firePropertyChange(String propertyName, float oldValue, + float newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, new Float(oldValue), + new Float(newValue)); + } + + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + * + * @since 1.5 + */ + public void firePropertyChange(String propertyName, double oldValue, + double newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, new Double(oldValue), + new Double(newValue)); + } + + /** * Sets the text layout orientation of this component. New components default * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only * the current component, while @@ -4597,7 +4710,7 @@ p * <li>the set of backward traversal keys */ static Event translateEvent (AWTEvent e) { - Component target = (Component) e.getSource (); + Object target = e.getSource (); Event translated = null; if (e instanceof InputEvent) @@ -4770,6 +4883,25 @@ p * <li>the set of backward traversal keys 0, 0, oldKey, oldMods); } } + else if (e instanceof AdjustmentEvent) + { + AdjustmentEvent ae = (AdjustmentEvent) e; + int type = ae.getAdjustmentType(); + int oldType; + if (type == AdjustmentEvent.BLOCK_DECREMENT) + oldType = Event.SCROLL_PAGE_UP; + else if (type == AdjustmentEvent.BLOCK_INCREMENT) + oldType = Event.SCROLL_PAGE_DOWN; + else if (type == AdjustmentEvent.TRACK) + oldType = Event.SCROLL_ABSOLUTE; + else if (type == AdjustmentEvent.UNIT_DECREMENT) + oldType = Event.SCROLL_LINE_UP; + else if (type == AdjustmentEvent.UNIT_INCREMENT) + oldType = Event.SCROLL_LINE_DOWN; + else + oldType = type; + translated = new Event(target, oldType, new Integer(ae.getValue())); + } else if (e instanceof ActionEvent) translated = new Event (target, Event.ACTION_EVENT, ((ActionEvent) e).getActionCommand ()); @@ -4790,16 +4922,16 @@ p * <li>the set of backward traversal keys void dispatchEventImpl(AWTEvent e) { - Event oldEvent = translateEvent (e); + // Give toolkit a chance to dispatch the event + // to globally registered listeners. + Toolkit.getDefaultToolkit().globalDispatchEvent(e); + // This boolean tells us not to process focus events when the focus // opposite component is the same as the focus component. boolean ignoreFocus = (e instanceof FocusEvent && ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent()); - if (oldEvent != null) - postEvent (oldEvent); - if (eventTypeEnabled (e.id)) { // the trick we use to communicate between dispatch and redispatch @@ -4925,16 +5057,6 @@ p * <li>the set of backward traversal keys Rectangle r1 = queuedEvent.getUpdateRect(); Rectangle r2 = newEvent.getUpdateRect(); Rectangle union = r1.union(r2); - - int r1a = r1.width * r1.height; - int r2a = r2.width * r2.height; - int ua = union.width * union.height; - - if (ua > (r1a+r2a)*2) - return null; - /* The 2 factor should maybe be reconsidered. Perhaps 3/2 - would be better? */ - newEvent.setUpdateRect(union); return newEvent; } @@ -5014,9 +5136,76 @@ p * <li>the set of backward traversal keys s.writeObject(null); } - + // Nested classes. + + /** + * This class fixes the bounds for a Heavyweight component that + * is placed inside a Lightweight container. When the lightweight is + * moved or resized, setBounds for the lightweight peer does nothing. + * Therefore, it was never moved on the screen. This class is + * attached to the lightweight, and it adjusts the position and size + * of the peer when notified. + * This is the same for show and hide. + */ + class HeavyweightInLightweightListener + implements ComponentListener + { + + /** + * Constructor. Adds component listener to lightweight parent. + * + * @param parent - the lightweight container. + */ + public HeavyweightInLightweightListener(Container parent) + { + parent.addComponentListener(this); + } + + /** + * This method is called when the component is resized. + * + * @param event the <code>ComponentEvent</code> indicating the resize + */ + public void componentResized(ComponentEvent event) + { + // Nothing to do here, componentMoved will be called. + } + + /** + * This method is called when the component is moved. + * + * @param event the <code>ComponentEvent</code> indicating the move + */ + public void componentMoved(ComponentEvent event) + { + if (peer != null) + peer.setBounds(x, y, width, height); + } + + /** + * This method is called when the component is made visible. + * + * @param event the <code>ComponentEvent</code> indicating the visibility + */ + public void componentShown(ComponentEvent event) + { + if (isShowing()) + peer.show(); + } + /** + * This method is called when the component is hidden. + * + * @param event the <code>ComponentEvent</code> indicating the visibility + */ + public void componentHidden(ComponentEvent event) + { + if (!isShowing()) + peer.hide(); + } + } + /** * This class provides accessibility support for subclasses of container. * diff --git a/libjava/classpath/java/awt/Container.java b/libjava/classpath/java/awt/Container.java index 67f0ed184d4..41892caeafa 100644 --- a/libjava/classpath/java/awt/Container.java +++ b/libjava/classpath/java/awt/Container.java @@ -1,5 +1,6 @@ /* Container.java -- parent container class in AWT - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation This file is part of GNU Classpath. @@ -42,12 +43,10 @@ import java.awt.event.ComponentListener; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -62,8 +61,6 @@ import java.util.Set; import javax.accessibility.Accessible; -import gnu.java.awt.AWTUtilities; - /** * A generic window toolkit object that acts as a container for other objects. * Components are tracked in a list, and new elements are at the end of the @@ -88,11 +85,14 @@ public class Container extends Component Component[] component; LayoutManager layoutMgr; - LightweightDispatcher dispatcher; - Dimension maxSize; /** + * Keeps track if the Container was cleared during a paint/update. + */ + private boolean backCleared; + + /** * @since 1.4 */ boolean focusCycleRoot; @@ -101,7 +101,6 @@ public class Container extends Component /* Anything else is non-serializable, and should be declared "transient". */ transient ContainerListener containerListener; - transient PropertyChangeSupport changeSupport; /** The focus traversal policy that determines how focus is transferred between this Container and its children. */ @@ -187,25 +186,6 @@ public class Container extends Component } /** - * Swaps the components at position i and j, in the container. - */ - - protected void swapComponents (int i, int j) - { - synchronized (getTreeLock ()) - { - if (i < 0 - || i >= component.length - || j < 0 - || j >= component.length) - throw new ArrayIndexOutOfBoundsException (); - Component tmp = component[i]; - component[i] = component[j]; - component[j] = tmp; - } - } - - /** * Returns the insets for this container, which is the space used for * borders, the margin, etc. * @@ -385,6 +365,8 @@ public class Container extends Component // Notify the layout manager. if (layoutMgr != null) { + // If we have a LayoutManager2 the constraints are "real", + // otherwise they are the "name" of the Component to add. if (layoutMgr instanceof LayoutManager2) { LayoutManager2 lm2 = (LayoutManager2) layoutMgr; @@ -393,7 +375,7 @@ public class Container extends Component else if (constraints instanceof String) layoutMgr.addLayoutComponent((String) constraints, comp); else - layoutMgr.addLayoutComponent(null, comp); + layoutMgr.addLayoutComponent("", comp); } // We previously only sent an event when this container is showing. @@ -428,8 +410,7 @@ public class Container extends Component for (int j = 0; j < list.length; j++) r.removeComponentListener(list[j]); - if (r.isShowing()) - r.removeNotify(); + r.removeNotify(); System.arraycopy(component, index + 1, component, index, ncomponents - index - 1); @@ -777,16 +758,17 @@ public class Container extends Component * a superclass method so that lightweight components are properly * drawn. * - * @param g The graphics context for this paint job. + * @param g - The graphics context for this paint job. */ public void paint(Graphics g) { if (!isShowing()) return; - // Visit heavyweights as well, in case they were - // erased when we cleared the background for this container. - visitChildren(g, GfxPaintVisitor.INSTANCE, false); + // Visit heavyweights if the background was cleared + // for this container. + visitChildren(g, GfxPaintVisitor.INSTANCE, !backCleared); + backCleared = false; } /** @@ -817,8 +799,11 @@ public class Container extends Component // also not cleared. So we do a check on !(peer instanceof LightweightPeer) // instead. ComponentPeer p = peer; - if (p != null && !(p instanceof LightweightPeer)) - g.clearRect(0, 0, getWidth(), getHeight()); + if (p != null && ! (p instanceof LightweightPeer)) + { + g.clearRect(0, 0, getWidth(), getHeight()); + backCleared = true; + } paint(g); } @@ -1557,28 +1542,105 @@ public class Container extends Component if (orientation == null) throw new NullPointerException (); } - + public void addPropertyChangeListener (PropertyChangeListener listener) { - if (listener == null) - return; - - if (changeSupport == null) - changeSupport = new PropertyChangeSupport (this); - - changeSupport.addPropertyChangeListener (listener); + // TODO: Why is this overridden? + super.addPropertyChangeListener(listener); } - - public void addPropertyChangeListener (String name, + + public void addPropertyChangeListener (String propertyName, PropertyChangeListener listener) { - if (listener == null) - return; - - if (changeSupport == null) - changeSupport = new PropertyChangeSupport (this); + // TODO: Why is this overridden? + super.addPropertyChangeListener(propertyName, listener); + } + + + /** + * Sets the Z ordering for the component <code>comp</code> to + * <code>index</code>. Components with lower Z order paint above components + * with higher Z order. + * + * @param comp the component for which to change the Z ordering + * @param index the index to set + * + * @throws NullPointerException if <code>comp == null</code> + * @throws IllegalArgumentException if comp is an ancestor of this container + * @throws IllegalArgumentException if <code>index</code> is not in + * <code>[0, getComponentCount()]</code> for moving between + * containers or <code>[0, getComponentCount() - 1]</code> for moving + * inside this container + * @throws IllegalArgumentException if <code>comp == this</code> + * @throws IllegalArgumentException if <code>comp</code> is a + * <code>Window</code> + * + * @see #getComponentZOrder(Component) + * + * @since 1.5 + */ + public final void setComponentZOrder(Component comp, int index) + { + if (comp == null) + throw new NullPointerException("comp must not be null"); + if (comp instanceof Container && ((Container) comp).isAncestorOf(this)) + throw new IllegalArgumentException("comp must not be an ancestor of " + + "this"); + if (comp instanceof Window) + throw new IllegalArgumentException("comp must not be a Window"); + + if (comp == this) + throw new IllegalArgumentException("cannot add component to itself"); + + // FIXME: Implement reparenting. + if ( comp.getParent() != this) + throw new AssertionError("Reparenting is not implemented yet"); + else + { + // Find current component index. + int currentIndex = getComponentZOrder(comp); + if (currentIndex < index) + { + System.arraycopy(component, currentIndex + 1, component, + currentIndex, index - currentIndex); + } + else + { + System.arraycopy(component, index, component, index + 1, + currentIndex - index); + } + component[index] = comp; + } + } - changeSupport.addPropertyChangeListener (name, listener); + /** + * Returns the Z ordering index of <code>comp</code>. If <code>comp</code> + * is not a child component of this Container, this returns <code>-1</code>. + * + * @param comp the component for which to query the Z ordering + * + * @return the Z ordering index of <code>comp</code> or <code>-1</code> if + * <code>comp</code> is not a child of this Container + * + * @see #setComponentZOrder(Component, int) + * + * @since 1.5 + */ + public final int getComponentZOrder(Component comp) + { + int index = -1; + if (component != null) + { + for (int i = 0; i < component.length; i++) + { + if (component[i] == comp) + { + index = i; + break; + } + } + } + return index; } // Hidden helper methods. @@ -1600,17 +1662,17 @@ public class Container extends Component private void visitChildren(Graphics gfx, GfxVisitor visitor, boolean lightweightOnly) { - synchronized (getTreeLock ()) + synchronized (getTreeLock()) { for (int i = ncomponents - 1; i >= 0; --i) { Component comp = component[i]; boolean applicable = comp.isVisible() - && (comp.isLightweight() || !lightweightOnly); - + && (comp.isLightweight() || ! lightweightOnly); + if (applicable) visitChild(gfx, visitor, comp); - } + } } } @@ -1631,10 +1693,9 @@ public class Container extends Component Component comp) { Rectangle bounds = comp.getBounds(); - + if(!gfx.hitClip(bounds.x,bounds.y, bounds.width, bounds.height)) return; - Graphics g2 = gfx.create(bounds.x, bounds.y, bounds.width, bounds.height); try @@ -1649,17 +1710,18 @@ public class Container extends Component void dispatchEventImpl(AWTEvent e) { - // Give lightweight dispatcher a chance to handle it. - if (dispatcher != null && dispatcher.handleEvent (e)) - return; - - if ((e.id <= ContainerEvent.CONTAINER_LAST - && e.id >= ContainerEvent.CONTAINER_FIRST) - && (containerListener != null - || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)) - processEvent(e); - else - super.dispatchEventImpl(e); + boolean dispatched = + LightweightDispatcher.getInstance().dispatchEvent(e); + if (! dispatched) + { + if ((e.id <= ContainerEvent.CONTAINER_LAST + && e.id >= ContainerEvent.CONTAINER_FIRST) + && (containerListener != null + || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)) + processEvent(e); + else + super.dispatchEventImpl(e); + } } /** @@ -1743,15 +1805,6 @@ public class Container extends Component component[i].addNotify(); if (component[i].isLightweight ()) { - - // If we're not lightweight, and we just got a lightweight - // child, we need a lightweight dispatcher to feed it events. - if (!this.isLightweight() && dispatcher == null) - dispatcher = new LightweightDispatcher (this); - - if (dispatcher != null) - dispatcher.enableEvents(component[i].eventMask); - enableEvents(component[i].eventMask); if (peer != null && !isLightweight ()) enableEvents (AWTEvent.PAINT_EVENT_MASK); @@ -1998,229 +2051,3 @@ public class Container extends Component } // class AccessibleContainerHandler } // class AccessibleAWTContainer } // class Container - -/** - * There is a helper class implied from stack traces called - * LightweightDispatcher, but since it is not part of the public API, - * rather than mimic it exactly we write something which does "roughly - * the same thing". - */ -class LightweightDispatcher implements Serializable -{ - private static final long serialVersionUID = 5184291520170872969L; - private Container nativeContainer; - private Cursor nativeCursor; - private long eventMask; - - private transient Component pressedComponent; - private transient Component lastComponentEntered; - private transient int pressCount; - - LightweightDispatcher(Container c) - { - nativeContainer = c; - } - - void enableEvents(long l) - { - eventMask |= l; - } - - /** - * Returns the deepest visible descendent of parent that contains the - * specified location and that is not transparent and MouseListener-less. - * @param parent the root component to begin the search - * @param x the x coordinate - * @param y the y coordinate - * @return null if <code>parent</code> doesn't contain the location, - * parent if parent is not a container or has no child that contains the - * location, otherwise the appropriate component from the conditions - * above. - */ - Component getDeepestComponentForMouseEventAt(Component parent, int x, int y) - { - if (parent == null || (! parent.contains(x, y))) - return null; - - if (! (parent instanceof Container)) - return parent; - - Container c = (Container) parent; - return c.findComponentForMouseEventAt(x, y); - } - - Component acquireComponentForMouseEvent(MouseEvent me) - { - int x = me.getX (); - int y = me.getY (); - - Component mouseEventTarget = null; - // Find the candidate which should receive this event. - Component parent = nativeContainer; - Component candidate = null; - Point p = me.getPoint(); - while (candidate == null && parent != null) - { - candidate = getDeepestComponentForMouseEventAt(parent, p.x, p.y); - if (candidate == null || (candidate.eventMask & me.getID()) == 0) - { - candidate = null; - p = AWTUtilities.convertPoint(parent, p.x, p.y, parent.parent); - parent = parent.parent; - } - } - - // If the only candidate we found was the native container itself, - // don't dispatch any event at all. We only care about the lightweight - // children here. - if (candidate == nativeContainer) - candidate = null; - - // If our candidate is new, inform the old target we're leaving. - if (lastComponentEntered != null - && lastComponentEntered.isShowing() - && lastComponentEntered != candidate) - { - // Old candidate could have been removed from - // the nativeContainer so we check first. - if (AWTUtilities.isDescendingFrom(lastComponentEntered, - nativeContainer)) - { - Point tp = AWTUtilities.convertPoint(nativeContainer, - x, y, lastComponentEntered); - MouseEvent exited = new MouseEvent (lastComponentEntered, - MouseEvent.MOUSE_EXITED, - me.getWhen (), - me.getModifiersEx (), - tp.x, tp.y, - me.getClickCount (), - me.isPopupTrigger (), - me.getButton ()); - lastComponentEntered.dispatchEvent (exited); - } - lastComponentEntered = null; - } - - // If we have a candidate, maybe enter it. - if (candidate != null) - { - mouseEventTarget = candidate; - if (candidate.isLightweight() - && candidate.isShowing() - && candidate != nativeContainer - && candidate != lastComponentEntered) - { - lastComponentEntered = mouseEventTarget; - Point cp = AWTUtilities.convertPoint(nativeContainer, - x, y, lastComponentEntered); - MouseEvent entered = new MouseEvent (lastComponentEntered, - MouseEvent.MOUSE_ENTERED, - me.getWhen (), - me.getModifiersEx (), - cp.x, cp.y, - me.getClickCount (), - me.isPopupTrigger (), - me.getButton ()); - lastComponentEntered.dispatchEvent (entered); - } - } - - // Check which buttons where pressed except the last button that - // changed state. - int modifiers = me.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK - | MouseEvent.BUTTON2_DOWN_MASK - | MouseEvent.BUTTON3_DOWN_MASK); - switch(me.getButton()) - { - case MouseEvent.BUTTON1: - modifiers &= ~MouseEvent.BUTTON1_DOWN_MASK; - break; - case MouseEvent.BUTTON2: - modifiers &= ~MouseEvent.BUTTON2_DOWN_MASK; - break; - case MouseEvent.BUTTON3: - modifiers &= ~MouseEvent.BUTTON3_DOWN_MASK; - break; - } - - if (me.getID() == MouseEvent.MOUSE_RELEASED - || me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0 - || me.getID() == MouseEvent.MOUSE_DRAGGED) - { - // If any of the following events occur while a button is held down, - // they should be dispatched to the same component to which the - // original MOUSE_PRESSED event was dispatched: - // - MOUSE_RELEASED: This is important for correct dragging - // behaviour, otherwise the release goes to an arbitrary component - // outside of the dragged component. OTOH, if there is no mouse - // drag while the mouse is pressed, the component under the mouse - // is the same as the previously pressed component anyway. - // - MOUSE_PRESSED: another button pressed while the first is held - // down - // - MOUSE_DRAGGED - if (AWTUtilities.isDescendingFrom(pressedComponent, nativeContainer)) - mouseEventTarget = pressedComponent; - } - else if (me.getID() == MouseEvent.MOUSE_CLICKED) - { - // Don't dispatch CLICKED events whose target is not the same as the - // target for the original PRESSED event. - if (candidate != pressedComponent) - { - mouseEventTarget = null; - pressCount = 0; - } - else if (pressCount == 0) - pressedComponent = null; - } - return mouseEventTarget; - } - - boolean handleEvent(AWTEvent e) - { - if (e instanceof MouseEvent) - { - MouseEvent me = (MouseEvent) e; - - // Make the LightWeightDispatcher reentrant. This is necessary when - // a lightweight component does its own modal event queue. - Component mouseEventTarget = acquireComponentForMouseEvent(me); - - // Avoid dispatching ENTERED and EXITED events twice. - if (mouseEventTarget != null - && mouseEventTarget.isShowing() - && e.getID() != MouseEvent.MOUSE_ENTERED - && e.getID() != MouseEvent.MOUSE_EXITED) - { - switch (e.getID()) - { - case MouseEvent.MOUSE_PRESSED: - if (pressCount++ == 0) - pressedComponent = mouseEventTarget; - break; - case MouseEvent.MOUSE_RELEASED: - // Clear our memory of the original PRESSED event, only if - // we're not expecting a CLICKED event after this. If - // there is a CLICKED event after this, it will do clean up. - if (--pressCount == 0 - && mouseEventTarget != pressedComponent) - { - pressedComponent = null; - pressCount = 0; - } - break; - } - - MouseEvent newEvt = - AWTUtilities.convertMouseEvent(nativeContainer, me, - mouseEventTarget); - mouseEventTarget.dispatchEvent(newEvt); - - if (newEvt.isConsumed()) - e.consume(); - } - } - - return e.isConsumed(); - } -} diff --git a/libjava/classpath/java/awt/Cursor.java b/libjava/classpath/java/awt/Cursor.java index 48a63f06f4f..0ff987cd9ed 100644 --- a/libjava/classpath/java/awt/Cursor.java +++ b/libjava/classpath/java/awt/Cursor.java @@ -219,6 +219,8 @@ public class Cursor implements java.io.Serializable public String toString() { - return (this.getClass() + "[" + getName() + "]"); + return (this.getClass() + + "[type=" + getType() + + ",name=" + getName() + "]"); } } diff --git a/libjava/classpath/java/awt/Frame.java b/libjava/classpath/java/awt/Frame.java index d6651f83e40..7003dac91fb 100644 --- a/libjava/classpath/java/awt/Frame.java +++ b/libjava/classpath/java/awt/Frame.java @@ -1,5 +1,6 @@ /* Frame.java -- AWT toplevel window - Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -57,143 +58,156 @@ import javax.accessibility.AccessibleStateSet; */ public class Frame extends Window implements MenuContainer { -/** - * Constant for the default cursor. - * @deprecated Replaced by <code>Cursor.DEFAULT_CURSOR</code> instead. - */ -public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR; -/** - * Constant for a cross-hair cursor. - * @deprecated Use <code>Cursor.CROSSHAIR_CURSOR</code> instead. - */ -public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR; + /** + * Constant for the default cursor. + * + * @deprecated Replaced by <code>Cursor.DEFAULT_CURSOR</code> instead. + */ + public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR; -/** - * Constant for a cursor over a text field. - * @deprecated Use <code>Cursor.TEXT_CURSOR</code> instead. - */ -public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR; + /** + * Constant for a cross-hair cursor. + * + * @deprecated Use <code>Cursor.CROSSHAIR_CURSOR</code> instead. + */ + public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR; -/** - * Constant for a cursor to display while waiting for an action to complete. - * @deprecated Use <code>Cursor.WAIT_CURSOR</code>. - */ -public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR; + /** + * Constant for a cursor over a text field. + * + * @deprecated Use <code>Cursor.TEXT_CURSOR</code> instead. + */ + public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR; -/** - * Cursor used over SW corner of window decorations. - * @deprecated Use <code>Cursor.SW_RESIZE_CURSOR</code> instead. - */ -public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR; + /** + * Constant for a cursor to display while waiting for an action to complete. + * + * @deprecated Use <code>Cursor.WAIT_CURSOR</code>. + */ + public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR; -/** - * Cursor used over SE corner of window decorations. - * @deprecated Use <code>Cursor.SE_RESIZE_CURSOR</code> instead. - */ -public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR; + /** + * Cursor used over SW corner of window decorations. + * + * @deprecated Use <code>Cursor.SW_RESIZE_CURSOR</code> instead. + */ + public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR; -/** - * Cursor used over NW corner of window decorations. - * @deprecated Use <code>Cursor.NW_RESIZE_CURSOR</code> instead. - */ -public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR; + /** + * Cursor used over SE corner of window decorations. + * @deprecated Use <code>Cursor.SE_RESIZE_CURSOR</code> instead. + */ + public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR; -/** - * Cursor used over NE corner of window decorations. - * @deprecated Use <code>Cursor.NE_RESIZE_CURSOR</code> instead. - */ -public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR; + /** + * Cursor used over NW corner of window decorations. + * + * @deprecated Use <code>Cursor.NW_RESIZE_CURSOR</code> instead. + */ + public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR; -/** - * Cursor used over N edge of window decorations. - * @deprecated Use <code>Cursor.N_RESIZE_CURSOR</code> instead. - */ -public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR; + /** + * Cursor used over NE corner of window decorations. + * + * @deprecated Use <code>Cursor.NE_RESIZE_CURSOR</code> instead. + */ + public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR; -/** - * Cursor used over S edge of window decorations. - * @deprecated Use <code>Cursor.S_RESIZE_CURSOR</code> instead. - */ -public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR; + /** + * Cursor used over N edge of window decorations. + * + * @deprecated Use <code>Cursor.N_RESIZE_CURSOR</code> instead. + */ + public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR; -/** - * Cursor used over E edge of window decorations. - * @deprecated Use <code>Cursor.E_RESIZE_CURSOR</code> instead. - */ -public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR; + /** + * Cursor used over S edge of window decorations. + * + * @deprecated Use <code>Cursor.S_RESIZE_CURSOR</code> instead. + */ + public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR; -/** - * Cursor used over W edge of window decorations. - * @deprecated Use <code>Cursor.W_RESIZE_CURSOR</code> instead. - */ -public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR; + /** + * Cursor used over E edge of window decorations. + * + * @deprecated Use <code>Cursor.E_RESIZE_CURSOR</code> instead. + */ + public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR; -/** - * Constant for a hand cursor. - * @deprecated Use <code>Cursor.HAND_CURSOR</code> instead. - */ -public static final int HAND_CURSOR = Cursor.HAND_CURSOR; + /** + * Cursor used over W edge of window decorations. + * + * @deprecated Use <code>Cursor.W_RESIZE_CURSOR</code> instead. + */ + public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR; -/** - * Constant for a cursor used during window move operations. - * @deprecated Use <code>Cursor.MOVE_CURSOR</code> instead. - */ -public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR; + /** + * Constant for a hand cursor. + * + * @deprecated Use <code>Cursor.HAND_CURSOR</code> instead. + */ + public static final int HAND_CURSOR = Cursor.HAND_CURSOR; -public static final int ICONIFIED = 1; -public static final int MAXIMIZED_BOTH = 6; -public static final int MAXIMIZED_HORIZ = 2; -public static final int MAXIMIZED_VERT = 4; -public static final int NORMAL = 0; + /** + * Constant for a cursor used during window move operations. + * + * @deprecated Use <code>Cursor.MOVE_CURSOR</code> instead. + */ + public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR; -// Serialization version constant -private static final long serialVersionUID = 2673458971256075116L; + public static final int ICONIFIED = 1; + public static final int MAXIMIZED_BOTH = 6; + public static final int MAXIMIZED_HORIZ = 2; + public static final int MAXIMIZED_VERT = 4; + public static final int NORMAL = 0; -/** - * @serial The version of the class data being serialized - * // FIXME: what is this value? - */ -private int frameSerializedDataVersion; +//Serialization version constant + private static final long serialVersionUID = 2673458971256075116L; -/** - * @serial Image used as the icon when this frame is minimized. - */ -private Image icon; + /** + * @serial The version of the class data being serialized + * FIXME: what is this value? + */ + private int frameSerializedDataVersion; -/** - * @serial Constant used by the JDK Motif peer set. Not used in - * this implementation. - */ -private boolean mbManagement; + /** + * @serial Image used as the icon when this frame is minimized. + */ + private Image icon; -/** - * @serial The menu bar for this frame. - */ -//private MenuBar menuBar = new MenuBar(); -private MenuBar menuBar; + /** + * @serial Constant used by the JDK Motif peer set. Not used in + * this implementation. + */ + private boolean mbManagement; -/** - * @serial A list of other top-level windows owned by this window. - */ -Vector ownedWindows = new Vector(); + /** + * @serial The menu bar for this frame. + */ + private MenuBar menuBar; -/** - * @serial Indicates whether or not this frame is resizable. - */ -private boolean resizable = true; + /** + * @serial A list of other top-level windows owned by this window. + */ + Vector ownedWindows = new Vector(); -/** - * @serial The state of this frame. - * // FIXME: What are the values here? - * This is package-private to avoid an accessor method. - */ -int state; + /** + * @serial Indicates whether or not this frame is resizable. + */ + private boolean resizable = true; -/** - * @serial The title of the frame. - */ -private String title = ""; + /** + * @serial The state of this frame. + * // FIXME: What are the values here? + * This is package-private to avoid an accessor method. + */ + int state; + + /** + * @serial The title of the frame. + */ + private String title = ""; /** * Maximized bounds for this frame. @@ -210,223 +224,235 @@ private String title = ""; */ private static transient long next_frame_number; -/** - * Initializes a new instance of <code>Frame</code> that is not visible - * and has no title. - */ -public -Frame() -{ - this(""); - noteFrame(this); -} + /** + * Initializes a new instance of <code>Frame</code> that is not visible + * and has no title. + */ + public Frame() + { + this(""); + noteFrame(this); + } -/** - * Initializes a new instance of <code>Frame</code> that is not visible - * and has the specified title. - * - * @param title The title of this frame. - */ -public -Frame(String title) -{ - super(); - this.title = title; - // Top-level frames are initially invisible. - visible = false; - noteFrame(this); -} + /** + * Initializes a new instance of <code>Frame</code> that is not visible + * and has the specified title. + * + * @param title the title of this frame + */ + public Frame(String title) + { + super(); + this.title = title; + // Top-level frames are initially invisible. + visible = false; + noteFrame(this); + } -public -Frame(GraphicsConfiguration gc) -{ - super(gc); - visible = false; - noteFrame(this); -} + public Frame(GraphicsConfiguration gc) + { + super(gc); + visible = false; + noteFrame(this); + } -public -Frame(String title, GraphicsConfiguration gc) -{ - super(gc); - setTitle(title); - visible = false; - noteFrame(this); -} + public Frame(String title, GraphicsConfiguration gc) + { + super(gc); + setTitle(title); + visible = false; + noteFrame(this); + } -/** - * Returns this frame's title string. - * - * @return This frame's title string. - */ -public String -getTitle() -{ - return(title); -} + /** + * Returns this frame's title string. + * + * @return this frame's title string + */ + public String getTitle() + { + return title; + } -/* - * Sets this frame's title to the specified value. - * - * @param title The new frame title. - */ -public synchronized void -setTitle(String title) -{ - this.title = title; - if (peer != null) - ((FramePeer) peer).setTitle(title); -} + /** + * Sets this frame's title to the specified value. + * + * @param title the new frame title + */ + public synchronized void setTitle(String title) + { + this.title = title; + if (peer != null) + ((FramePeer) peer).setTitle(title); + } -/** - * Returns this frame's icon. - * - * @return This frame's icon, or <code>null</code> if this frame does not - * have an icon. - */ -public Image -getIconImage() -{ - return(icon); -} + /** + * Returns this frame's icon. + * + * @return this frame's icon, or <code>null</code> if this frame does not + * have an icon + */ + public Image getIconImage() + { + return icon; + } -/** - * Sets this frame's icon to the specified value. - * - * @icon The new icon for this frame. - */ -public synchronized void -setIconImage(Image icon) -{ - this.icon = icon; - if (peer != null) - ((FramePeer) peer).setIconImage(icon); -} + /** + * Sets this frame's icon to the specified value. + * + * @icon the new icon for this frame + */ + public synchronized void setIconImage(Image icon) + { + this.icon = icon; + if (peer != null) + ((FramePeer) peer).setIconImage(icon); + } -/** - * Returns this frame's menu bar. - * - * @return This frame's menu bar, or <code>null</code> if this frame - * does not have a menu bar. - */ -public MenuBar -getMenuBar() -{ - return(menuBar); -} + /** + * Returns this frame's menu bar. + * + * @return this frame's menu bar, or <code>null</code> if this frame + * does not have a menu bar + */ + public MenuBar getMenuBar() + { + return menuBar; + } -/** - * Sets this frame's menu bar. - * - * @param menuBar The new menu bar for this frame. - */ -public synchronized void -setMenuBar(MenuBar menuBar) -{ - if (peer != null) + /** + * Sets this frame's menu bar. Removes any existing menu bar. If the + * given menu bar is part of another frame it will be removed from + * that frame. + * + * @param menuBar the new menu bar for this frame + */ + public synchronized void setMenuBar(MenuBar menuBar) { if (this.menuBar != null) - this.menuBar.removeNotify(); + remove(this.menuBar); + + this.menuBar = menuBar; if (menuBar != null) - menuBar.addNotify(); - invalidateTree (); - ((FramePeer) peer).setMenuBar(menuBar); + { + MenuContainer parent = menuBar.getParent(); + if (parent != null) + parent.remove(menuBar); + menuBar.setParent(this); + + if (peer != null) + { + if (menuBar != null) + menuBar.addNotify(); + invalidateTree(); + ((FramePeer) peer).setMenuBar(menuBar); + } + } } - this.menuBar = menuBar; -} -/** - * Tests whether or not this frame is resizable. This will be - * <code>true</code> by default. - * - * @return <code>true</code> if this frame is resizable, <code>false</code> - * otherwise. - */ -public boolean -isResizable() -{ - return(resizable); -} + /** + * Tests whether or not this frame is resizable. This will be + * <code>true</code> by default. + * + * @return <code>true</code> if this frame is resizable, <code>false</code> + * otherwise + */ + public boolean isResizable() + { + return resizable; + } -/** - * Sets the resizability of this frame to the specified value. - * - * @param resizable <code>true</code> to make the frame resizable, - * <code>false</code> to make it non-resizable. - */ -public synchronized void -setResizable(boolean resizable) -{ - this.resizable = resizable; - if (peer != null) - ((FramePeer) peer).setResizable(resizable); -} + /** + * Sets the resizability of this frame to the specified value. + * + * @param resizable <code>true</code> to make the frame resizable, + * <code>false</code> to make it non-resizable + */ + public synchronized void setResizable(boolean resizable) + { + this.resizable = resizable; + if (peer != null) + ((FramePeer) peer).setResizable(resizable); + } -/** - * Returns the cursor type of the cursor for this window. This will - * be one of the constants in this class. - * - * @return The cursor type for this frame. - * - * @deprecated Use <code>Component.getCursor()</code> instead. - */ -public int -getCursorType() -{ - return(getCursor().getType()); -} + /** + * Returns the cursor type of the cursor for this window. This will + * be one of the constants in this class. + * + * @return the cursor type for this frame + * + * @deprecated Use <code>Component.getCursor()</code> instead. + */ + public int getCursorType() + { + return getCursor().getType(); + } -/** - * Sets the cursor for this window to the specified type. The specified - * type should be one of the constants in this class. - * - * @param type The cursor type. - * - * @deprecated Use <code>Component.setCursor(Cursor)</code> instead. - */ -public void -setCursor(int type) -{ - setCursor(new Cursor(type)); -} + /** + * Sets the cursor for this window to the specified type. The specified + * type should be one of the constants in this class. + * + * @param type the cursor type + * + * @deprecated Use <code>Component.setCursor(Cursor)</code> instead. + */ + public void setCursor(int type) + { + setCursor(new Cursor(type)); + } -/** - * Removes the specified component from this frame's menu. - * - * @param menu The menu component to remove. - */ -public void -remove(MenuComponent menu) -{ - menuBar.remove(menu); -} + /** + * Removes the specified menu component from this frame. If it is + * the current MenuBar it is removed from the frame. If it is a + * Popup it is removed from this component. If it is any other menu + * component it is ignored. + * + * @param menu the menu component to remove + */ + public void remove(MenuComponent menu) + { + if (menu == menuBar) + { + if (menuBar != null) + { + if (peer != null) + { + ((FramePeer) peer).setMenuBar(null); + menuBar.removeNotify(); + } + menuBar.setParent(null); + } + menuBar = null; + } + else + super.remove(menu); + } -public void -addNotify() -{ - if (menuBar != null) - menuBar.addNotify(); - if (peer == null) - peer = getToolkit ().createFrame (this); + public void addNotify() + { + if (menuBar != null) + menuBar.addNotify(); + if (peer == null) + peer = getToolkit ().createFrame (this); - super.addNotify(); -} + super.addNotify(); + } -public void removeNotify() -{ - if (menuBar != null) - menuBar.removeNotify(); - super.removeNotify(); -} + public void removeNotify() + { + if (menuBar != null) + menuBar.removeNotify(); + super.removeNotify(); + } /** * Returns a debugging string describing this window. * - * @return A debugging string describing this window. + * @return a debugging string describing this window */ - protected String paramString () + protected String paramString() { - String title = getTitle (); + String title = getTitle(); String resizable = ""; if (isResizable ()) @@ -455,17 +481,17 @@ public void removeNotify() return super.paramString () + ",title=" + title + resizable + state; } -private static ArrayList weakFrames = new ArrayList(); + private static ArrayList weakFrames = new ArrayList(); -private static void noteFrame(Frame f) -{ - weakFrames.add(new WeakReference(f)); -} + private static void noteFrame(Frame f) + { + weakFrames.add(new WeakReference(f)); + } -public static Frame[] getFrames() -{ - int n = 0; - synchronized (weakFrames) + public static Frame[] getFrames() + { + int n = 0; + synchronized (weakFrames) { Iterator i = weakFrames.iterator(); while (i.hasNext()) @@ -490,32 +516,31 @@ public static Frame[] getFrames() return frames; } } -} + } - public void setState (int state) + public void setState(int state) { int current_state = getExtendedState (); if (state == NORMAL && (current_state & ICONIFIED) != 0) - setExtendedState (current_state | ICONIFIED); + setExtendedState(current_state | ICONIFIED); if (state == ICONIFIED && (current_state & ~ICONIFIED) == 0) - setExtendedState (current_state & ~ICONIFIED); + setExtendedState(current_state & ~ICONIFIED); } - public int getState () + public int getState() { - /* FIXME: State might have changed in the peer... Must check. */ - + // FIXME: State might have changed in the peer... Must check. return (state & ICONIFIED) != 0 ? ICONIFIED : NORMAL; } /** * @since 1.4 */ - public void setExtendedState (int state) + public void setExtendedState(int state) { this.state = state; } @@ -523,7 +548,7 @@ public static Frame[] getFrames() /** * @since 1.4 */ - public int getExtendedState () + public int getExtendedState() { return state; } @@ -531,7 +556,7 @@ public static Frame[] getFrames() /** * @since 1.4 */ - public void setMaximizedBounds (Rectangle maximizedBounds) + public void setMaximizedBounds(Rectangle maximizedBounds) { this.maximizedBounds = maximizedBounds; } @@ -539,11 +564,11 @@ public static Frame[] getFrames() /** * Returns the maximized bounds of this frame. * - * @return the maximized rectangle, may be null. + * @return the maximized rectangle, may be null * * @since 1.4 */ - public Rectangle getMaximizedBounds () + public Rectangle getMaximizedBounds() { return maximizedBounds; } @@ -553,7 +578,7 @@ public static Frame[] getFrames() * * @since 1.4 */ - public boolean isUndecorated () + public boolean isUndecorated() { return undecorated; } @@ -562,14 +587,14 @@ public static Frame[] getFrames() * Disables or enables decorations for this frame. This method can only be * called while the frame is not displayable. * - * @exception IllegalComponentStateException If this frame is displayable. + * @throws IllegalComponentStateException if this frame is displayable * * @since 1.4 */ - public void setUndecorated (boolean undecorated) + public void setUndecorated(boolean undecorated) { - if (isDisplayable ()) - throw new IllegalComponentStateException (); + if (isDisplayable()) + throw new IllegalComponentStateException(); this.undecorated = undecorated; } @@ -577,14 +602,14 @@ public static Frame[] getFrames() /** * Generate a unique name for this frame. * - * @return A unique name for this frame. + * @return a unique name for this frame */ - String generateName () + String generateName() { - return "frame" + getUniqueLong (); + return "frame" + getUniqueLong(); } - private static synchronized long getUniqueLong () + private static synchronized long getUniqueLong() { return next_frame_number++; } @@ -617,10 +642,9 @@ public static Frame[] getFrames() */ public AccessibleContext getAccessibleContext() { - /* Create the context if this is the first request */ + // Create the context if this is the first request. if (accessibleContext == null) accessibleContext = new AccessibleAWTFrame(); return accessibleContext; } - } diff --git a/libjava/classpath/java/awt/Insets.java b/libjava/classpath/java/awt/Insets.java index 7238a34e22a..6d5bd122e9d 100644 --- a/libjava/classpath/java/awt/Insets.java +++ b/libjava/classpath/java/awt/Insets.java @@ -100,11 +100,31 @@ public class Insets implements Cloneable, Serializable } /** + * Set the contents of this Insets object to the specified values. + * + * @param top the top inset + * @param left the left inset + * @param bottom the bottom inset + * @param right the right inset + * + * @since 1.5 + */ + public void set(int top, int left, int bottom, int right) + { + this.top = top; + this.left = left; + this.bottom = bottom; + this.right = right; + } + + /** * Tests whether this object is equal to the specified object. The other * object must be an instance of Insets with identical field values. * * @param obj the object to test against * @return true if the specified object is equal to this one + * + * @since 1.1 */ public boolean equals(Object obj) { diff --git a/libjava/classpath/java/awt/LightweightDispatcher.java b/libjava/classpath/java/awt/LightweightDispatcher.java new file mode 100644 index 00000000000..6573b128ec4 --- /dev/null +++ b/libjava/classpath/java/awt/LightweightDispatcher.java @@ -0,0 +1,200 @@ +/* LightweightDispatcher.java -- Dispatches mouse events to lightweights + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import gnu.java.awt.AWTUtilities; + +import java.awt.event.MouseEvent; +import java.util.WeakHashMap; + +/** + * Redispatches mouse events to lightweight components. The native peers know + * nothing about the lightweight components and thus mouse events are always + * targetted at Windows or heavyweight components. This class listenes directly + * on the eventqueue and dispatches mouse events to lightweight components. + * + * @author Roman Kennke (kennke@aicas.com) + */ +class LightweightDispatcher +{ + + /** + * Maps thread groups to lightweight dispatcher instances. We need to + * have one instance per thread group so that 2 or more applets or otherwise + * separated applications (like in OSGI) do not interfer with each other. + */ + private static WeakHashMap instances = new WeakHashMap(); + + /** + * The component that is the start of a mouse dragging. All MOUSE_DRAGGED + * events that follow the initial press must have the source set to this, + * as well as the MOUSE_RELEASED event following the dragging. + */ + private Component dragTarget; + + /** + * The last mouse event target. If the target changes, additional + * MOUSE_ENTERED and MOUSE_EXITED events must be dispatched. + */ + private Component lastTarget; + + /** + * Returns an instance of LightweightDispatcher for the current thread's + * thread group. + * + * @return an instance of LightweightDispatcher for the current thread's + * thread group + */ + static LightweightDispatcher getInstance() + { + Thread t = Thread.currentThread(); + ThreadGroup tg = t.getThreadGroup(); + LightweightDispatcher instance = (LightweightDispatcher) instances.get(tg); + if (instance == null) + { + instance = new LightweightDispatcher(); + instances.put(tg, instance); + } + return instance; + } + + /** + * Creates a new LightweightDispatcher. This is private to prevent access + * from outside. Use {@link #getInstance()} instead. + */ + private LightweightDispatcher() + { + // Nothing to do here. + } + + /** + * Receives notification if a mouse event passes along the eventqueue. + * + * @param event the event + */ + public boolean dispatchEvent(AWTEvent event) + { + boolean dispatched = false; + if (event instanceof MouseEvent && event.getSource() instanceof Window) + { + MouseEvent mouseEvent = (MouseEvent) event; + handleMouseEvent(mouseEvent); + dispatched = true; + } + return dispatched; + } + + /** + * Handles all mouse events that are targetted at toplevel containers + * (Window instances) and dispatches them to the correct lightweight child. + * + * @param ev the mouse event + */ + private void handleMouseEvent(MouseEvent ev) + { + Window window = (Window) ev.getSource(); + Component target = window.findComponentAt(ev.getX(), ev.getY()); + if (target != null && target.isLightweight()) + { + // Dispatch additional MOUSE_EXITED and MOUSE_ENTERED if event target + // is different from the last event target. + if (target != lastTarget) + { + if (lastTarget != null) + { + Point p1 = AWTUtilities.convertPoint(window, ev.getX(), + ev.getY(), lastTarget); + MouseEvent mouseExited = + new MouseEvent(lastTarget, MouseEvent.MOUSE_EXITED, + ev.getWhen(), ev.getModifiers(), p1.x, p1.y, + ev.getClickCount(), ev.isPopupTrigger()); + lastTarget.dispatchEvent(mouseExited); + } + Point p = AWTUtilities.convertPoint(window, ev.getX(), ev.getY(), + target); + MouseEvent mouseEntered = + new MouseEvent(target, MouseEvent.MOUSE_ENTERED, ev.getWhen(), + ev.getModifiers(), p.x, p.y, ev.getClickCount(), + ev.isPopupTrigger()); + target.dispatchEvent(mouseEntered); + } + + switch (ev.getID()) + { + case MouseEvent.MOUSE_PRESSED: + dragTarget = target; + break; + case MouseEvent.MOUSE_RELEASED: + if (dragTarget != null) + target = dragTarget; + dragTarget = null; + break; + case MouseEvent.MOUSE_CLICKED: + // When we receive a MOUSE_CLICKED, we set the target to the + // previous target, which must have been a MOUSE_RELEASED event. + // This is necessary for the case when the MOUSE_RELEASED has + // caused the original target (like an internal component) go + // away. + target = lastTarget; + break; + case MouseEvent.MOUSE_DRAGGED: + target = dragTarget; + break; + default: + // Do nothing in other cases. + break; + } + + lastTarget = target; + + Point targetCoordinates = + AWTUtilities.convertPoint(window, ev.getX(), ev.getY(), target); + int dx = targetCoordinates.x - ev.getX(); + int dy = targetCoordinates.y - ev.getY(); + ev.translatePoint(dx, dy); + ev.setSource(target); + target.dispatchEvent(ev); + + // We reset the event, so that the normal event dispatching is not + // influenced by this modified event. + ev.setSource(window); + ev.translatePoint(-dx, -dy); + } + } +} diff --git a/libjava/classpath/java/awt/Menu.java b/libjava/classpath/java/awt/Menu.java index 13ebb5211be..6daec72cf44 100644 --- a/libjava/classpath/java/awt/Menu.java +++ b/libjava/classpath/java/awt/Menu.java @@ -1,5 +1,5 @@ /* Menu.java -- A Java AWT Menu - Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -220,15 +220,16 @@ getItem(int index) public MenuItem add(MenuItem item) { + MenuContainer parent = item.getParent(); + if (parent != null) + parent.remove(item); + items.addElement(item); - if (item.parent != null) - { - item.parent.remove(item); - } - item.parent = this; + item.setParent(this); if (peer != null) { + item.addNotify(); MenuPeer mp = (MenuPeer) peer; mp.addItem(item); } @@ -266,26 +267,33 @@ insert(MenuItem item, int index) if (index < 0) throw new IllegalArgumentException("Index is less than zero"); - MenuPeer peer = (MenuPeer) getPeer(); - if (peer == null) - return; - int count = getItemCount (); if (index >= count) - peer.addItem (item); + add(item); else { + MenuContainer parent = item.getParent(); + if (parent != null) + parent.remove(item); + + items.insertElementAt(item, index); + item.setParent(this); + + MenuPeer peer = (MenuPeer) getPeer(); + if (peer == null) + return; + for (int i = count - 1; i >= index; i--) - peer.delItem (i); + peer.delItem(i); - peer.addItem (item); + item.addNotify(); + peer.addItem(item); for (int i = index; i < count; i++) - peer.addItem ((MenuItem) items.elementAt (i)); + peer.addItem((MenuItem) items.elementAt (i)); } - items.insertElementAt(item, index); } /*************************************************************************/ @@ -344,11 +352,15 @@ insertSeparator(int index) public synchronized void remove(int index) { - items.removeElementAt(index); + MenuItem item = (MenuItem) items.remove(index); - MenuPeer mp = (MenuPeer)getPeer(); + MenuPeer mp = (MenuPeer) getPeer(); if (mp != null) - mp.delItem(index); + { + mp.delItem(index); + item.removeNotify(); + } + item.setParent(null); } /*************************************************************************/ @@ -393,14 +405,21 @@ removeAll() public void addNotify() { + MenuPeer peer = (MenuPeer) getPeer(); if (peer == null) - peer = getToolkit().createMenu(this); + { + peer = getToolkit().createMenu(this); + setPeer(peer); + } + Enumeration e = items.elements(); while (e.hasMoreElements()) { MenuItem mi = (MenuItem)e.nextElement(); mi.addNotify(); - } + peer.addItem(mi); + } + super.addNotify (); } diff --git a/libjava/classpath/java/awt/MenuBar.java b/libjava/classpath/java/awt/MenuBar.java index 4089fe189e0..3c6b915649f 100644 --- a/libjava/classpath/java/awt/MenuBar.java +++ b/libjava/classpath/java/awt/MenuBar.java @@ -1,5 +1,6 @@ /* MenuBar.java -- An AWT menu bar class - Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,7 +40,6 @@ exception statement from your version. */ package java.awt; import java.awt.peer.MenuBarPeer; -import java.awt.peer.MenuComponentPeer; import java.io.Serializable; import java.util.Enumeration; @@ -60,364 +60,311 @@ public class MenuBar extends MenuComponent implements MenuContainer, Serializable, Accessible { -/* - * Static Variables - */ +//Serialization Constant + private static final long serialVersionUID = -4930327919388951260L; -// Serialization Constant -private static final long serialVersionUID = -4930327919388951260L; - -/*************************************************************************/ - -/* - * Instance Variables - */ - -/** - * @serial The menu used for providing help information - */ -private Menu helpMenu; + /** + * @serial The menu used for providing help information + */ + private Menu helpMenu; -/** - * @serial The menus contained in this menu bar. - */ -private Vector menus = new Vector(); + /** + * @serial The menus contained in this menu bar. + */ + private Vector menus = new Vector(); /** - * The accessible context for this component. + * Initializes a new instance of <code>MenuBar</code>. * - * @see #getAccessibleContext() - * @serial ignored. + * @throws HeadlessException if GraphicsEnvironment.isHeadless() is true */ - private transient AccessibleContext accessibleContext; - -/*************************************************************************/ - -/* - * Constructors - */ - -/** - * Initializes a new instance of <code>MenuBar</code>. - * - * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. - */ -public -MenuBar() -{ - if (GraphicsEnvironment.isHeadless()) - throw new HeadlessException (); -} - -/*************************************************************************/ - -/* - * Instance Methods - */ - -/** - * Returns the help menu for this menu bar. This may be <code>null</code>. - * - * @return The help menu for this menu bar. - */ -public Menu -getHelpMenu() -{ - return(helpMenu); -} - -/*************************************************************************/ - -/** - * Sets the help menu for this menu bar. - * - * @param menu The new help menu for this menu bar. - */ -public synchronized void -setHelpMenu(Menu menu) -{ - if (helpMenu != null) - { - helpMenu.removeNotify (); - helpMenu.parent = null; - } - helpMenu = menu; - - if (menu.parent != null) - menu.parent.remove (menu); - menu.parent = this; - - MenuBarPeer peer = (MenuBarPeer) getPeer (); - if (peer != null) - { - menu.addNotify(); - peer.addHelpMenu (menu); - } -} - -/*************************************************************************/ - -/** Add a menu to this MenuBar. If the menu has already has a - * parent, it is first removed from its old parent before being - * added. - * - * @param menu The menu to add. - * - * @return The menu that was added. - */ -public synchronized Menu -add(Menu menu) -{ - if (menu.parent != null) - menu.parent.remove (menu); - - menu.parent = this; - menus.addElement(menu); - - if (peer != null) - { - menu.addNotify(); - } - - return(menu); -} - -/*************************************************************************/ + public MenuBar() + { + if (GraphicsEnvironment.isHeadless()) + throw new HeadlessException(); + } -/** - * Removes the menu at the specified index. - * - * @param index The index of the menu to remove from the menu bar. - */ -public synchronized void -remove(int index) -{ - Menu m = (Menu) menus.get (index); - menus.remove (index); - m.removeNotify (); - m.parent = null; + /** + * Returns the help menu for this menu bar. This may be <code>null</code>. + * + * @return the help menu for this menu bar + */ + public Menu getHelpMenu() + { + return helpMenu; + } - if (peer != null) - { - MenuBarPeer mp = (MenuBarPeer) peer; - mp.delMenu (index); - } -} + /** + * Sets the help menu for this menu bar. + * + * @param menu the new help menu for this menu bar + */ + public synchronized void setHelpMenu(Menu menu) + { + MenuBarPeer myPeer = (MenuBarPeer) getPeer (); + + if (helpMenu != null) + { + if (myPeer != null) + helpMenu.removeNotify(); + helpMenu.setParent(null); + } + helpMenu = menu; + + MenuContainer parent = menu.getParent(); + if (parent != null) + parent.remove(menu); + menu.setParent(this); + + if (myPeer != null) + { + menu.addNotify(); + myPeer.addHelpMenu(menu); + } + } -/*************************************************************************/ + /** + * Add a menu to this MenuBar. If the menu has already has a + * parent, it is first removed from its old parent before being + * added. + * + * @param menu the menu to add + * + * @return the menu that was added + */ + public synchronized Menu add(Menu menu) + { + MenuBarPeer myPeer = (MenuBarPeer) getPeer (); -/** - * Removes the specified menu from the menu bar. - * - * @param menu The menu to remove from the menu bar. - */ -public void -remove(MenuComponent menu) -{ - int index = menus.indexOf(menu); - if (index == -1) - return; + MenuContainer parent = menu.getParent(); + if (parent != null) + parent.remove(menu); - remove(index); -} + menus.addElement(menu); + menu.setParent(this); -/*************************************************************************/ + if (myPeer != null) + { + menu.addNotify(); + myPeer.addMenu(menu); + } + return menu; + } -/** - * Returns the number of elements in this menu bar. - * - * @return The number of elements in the menu bar. - */ -public int -getMenuCount() -{ - return countMenus (); -} + /** + * Removes the menu at the specified index. + * + * @param index the index of the menu to remove from the menu bar + */ + public synchronized void remove(int index) + { + Menu m = (Menu) menus.remove(index); + MenuBarPeer mp = (MenuBarPeer) getPeer(); -/*************************************************************************/ + if (mp != null) + m.removeNotify(); -/** - * Returns the number of elements in this menu bar. - * - * @return The number of elements in the menu bar. - * - * @deprecated This method is deprecated in favor of <code>getMenuCount()</code>. - */ -public int -countMenus() -{ - return menus.size () + (getHelpMenu () == null ? 0 : 1); -} + m.setParent(null); -/*************************************************************************/ + if (mp != null) + mp.delMenu(index); + } -/** - * Returns the menu at the specified index. - * - * @param index the index of the menu - * - * @return The requested menu. - * - * @exception ArrayIndexOutOfBoundsException If the index is not valid. - */ -public Menu -getMenu(int index) -{ - return((Menu)menus.elementAt(index)); -} + /** + * Removes the specified menu from the menu bar. + * + * @param menu the menu to remove from the menu bar + */ + public void remove(MenuComponent menu) + { + int index = menus.indexOf(menu); + if (index == -1) + return; -/*************************************************************************/ + remove(index); + } -/** - * Creates this object's native peer. - */ -public void -addNotify() -{ - if (getPeer() == null) - setPeer((MenuComponentPeer)getToolkit().createMenuBar(this)); - Enumeration e = menus.elements(); - while (e.hasMoreElements()) + /** + * Returns the number of elements in this menu bar. + * + * @return the number of elements in the menu bar + */ + public int getMenuCount() { - Menu mi = (Menu)e.nextElement(); - mi.addNotify(); + return countMenus(); } - if (helpMenu != null) + + /** + * Returns the number of elements in this menu bar. + * + * @return the number of elements in the menu bar + * + * @deprecated This method is deprecated in favor of + * <code>getMenuCount()</code>. + */ + public int countMenus() { - helpMenu.addNotify(); - ((MenuBarPeer) peer).addHelpMenu(helpMenu); + return menus.size() + (getHelpMenu() == null ? 0 : 1); } -} -/*************************************************************************/ - -/** - * Destroys this object's native peer. - */ -public void -removeNotify() -{ - Enumeration e = menus.elements(); - while (e.hasMoreElements()) + /** + * Returns the menu at the specified index. + * + * @param index the index of the menu + * + * @return the requested menu + * + * @throws ArrayIndexOutOfBoundsException if the index is not valid + */ + public Menu getMenu(int index) { - Menu mi = (Menu) e.nextElement(); - mi.removeNotify(); + return (Menu) menus.elementAt(index); } - super.removeNotify(); -} - -/*************************************************************************/ - -/** - * Returns a list of all shortcuts for the menus in this menu bar. - * - * @return A list of all shortcuts for the menus in this menu bar. - */ -public synchronized Enumeration -shortcuts() -{ - Vector shortcuts = new Vector(); - Enumeration e = menus.elements(); - - while (e.hasMoreElements()) - { - Menu menu = (Menu)e.nextElement(); - if (menu.getShortcut() != null) - shortcuts.addElement(menu.getShortcut()); - } - return(shortcuts.elements()); -} + /** + * Creates this object's native peer. + */ + public void addNotify() + { + MenuBarPeer peer = (MenuBarPeer) getPeer(); + if (peer == null) + { + peer = getToolkit().createMenuBar(this); + setPeer(peer); + } + + Enumeration e = menus.elements(); + while (e.hasMoreElements()) + { + Menu mi = (Menu)e.nextElement(); + mi.addNotify(); + peer.addMenu(mi); + } + + if (helpMenu != null) + { + helpMenu.addNotify(); + peer.addHelpMenu(helpMenu); + } + } -/*************************************************************************/ + /** + * Destroys this object's native peer. + */ + public void removeNotify() + { + Enumeration e = menus.elements(); + while (e.hasMoreElements()) + { + Menu mi = (Menu) e.nextElement(); + mi.removeNotify(); + } + super.removeNotify(); + } -/** - * Returns the menu item for the specified shortcut, or <code>null</code> - * if no such item exists. - * - * @param shortcut The shortcut to return the menu item for. - * - * @return The menu item for the specified shortcut. - */ -public MenuItem -getShortcutMenuItem(MenuShortcut shortcut) -{ - Enumeration e = menus.elements(); + /** + * Returns a list of all shortcuts for the menus in this menu bar. + * + * @return a list of all shortcuts for the menus in this menu bar + */ + public synchronized Enumeration shortcuts() + { + Vector shortcuts = new Vector(); + Enumeration e = menus.elements(); - while (e.hasMoreElements()) - { - Menu menu = (Menu)e.nextElement(); - MenuShortcut s = menu.getShortcut(); - if ((s != null) && (s.equals(shortcut))) - return(menu); - } + while (e.hasMoreElements()) + { + Menu menu = (Menu)e.nextElement(); + if (menu.getShortcut() != null) + shortcuts.addElement(menu.getShortcut()); + } - return(null); -} + return shortcuts.elements(); + } -/*************************************************************************/ + /** + * Returns the menu item for the specified shortcut, or <code>null</code> + * if no such item exists. + * + * @param shortcut the shortcut to return the menu item for + * + * @return the menu item for the specified shortcut + */ + public MenuItem getShortcutMenuItem(MenuShortcut shortcut) + { + Enumeration e = menus.elements(); -/** - * Deletes the specified menu shortcut. - * - * @param shortcut The shortcut to delete. - */ -public void -deleteShortcut(MenuShortcut shortcut) -{ - MenuItem it; - // This is a slow implementation, but it probably doesn't matter. - while ((it = getShortcutMenuItem (shortcut)) != null) - it.deleteShortcut (); -} + while (e.hasMoreElements()) + { + Menu menu = (Menu) e.nextElement(); + MenuShortcut s = menu.getShortcut(); + if ((s != null) && s.equals(shortcut)) + return menu; + } -/** - * Gets the AccessibleContext associated with this <code>MenuBar</code>. - * The context is created, if necessary. - * - * @return the associated context - */ -public AccessibleContext getAccessibleContext() -{ - /* Create the context if this is the first request */ - if (accessibleContext == null) - accessibleContext = new AccessibleAWTMenuBar(); - return accessibleContext; -} + return null; + } -/** - * This class provides accessibility support for AWT menu bars. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ -protected class AccessibleAWTMenuBar - extends AccessibleAWTMenuComponent -{ - /** - * Compatible with JDK 1.4.2 revision 5 + * Deletes the specified menu shortcut. + * + * @param shortcut the shortcut to delete */ - private static final long serialVersionUID = -8577604491830083815L; + public void deleteShortcut(MenuShortcut shortcut) + { + MenuItem it; + // This is a slow implementation, but it probably doesn't matter. + while ((it = getShortcutMenuItem (shortcut)) != null) + it.deleteShortcut(); + } /** - * This is the default constructor, which simply calls the default - * constructor of the superclass. + * Gets the AccessibleContext associated with this <code>MenuBar</code>. + * The context is created, if necessary. + * + * @return the associated context */ - protected AccessibleAWTMenuBar() + public AccessibleContext getAccessibleContext() { - super(); + // Create the context if this is the first request. + if (accessibleContext == null) + accessibleContext = new AccessibleAWTMenuBar(); + return accessibleContext; } /** - * Returns the accessible role relating to the menu bar. + * This class provides accessibility support for AWT menu bars. * - * @return <code>AccessibleRole.MENU_BAR</code>. + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) */ - public AccessibleRole getAccessibleRole() + protected class AccessibleAWTMenuBar + extends AccessibleAWTMenuComponent { - return AccessibleRole.MENU_BAR; - } + + /** + * Compatible with JDK 1.4.2 revision 5 + */ + private static final long serialVersionUID = -8577604491830083815L; + + /** + * This is the default constructor, which simply calls the default + * constructor of the superclass. + */ + protected AccessibleAWTMenuBar() + { + super(); + } -} // class AccessibleAWTMenuBar + /** + * Returns the accessible role relating to the menu bar. + * + * @return <code>AccessibleRole.MENU_BAR</code> + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.MENU_BAR; + } -} // class MenuBar + } + +} diff --git a/libjava/classpath/java/awt/MenuComponent.java b/libjava/classpath/java/awt/MenuComponent.java index 375d08436e0..9bb875069e0 100644 --- a/libjava/classpath/java/awt/MenuComponent.java +++ b/libjava/classpath/java/awt/MenuComponent.java @@ -1,5 +1,6 @@ /* MenuComponent.java -- Superclass of all AWT menu components - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -60,26 +61,16 @@ import javax.accessibility.AccessibleStateSet; public abstract class MenuComponent implements Serializable { -/* - * Static Variables - */ +//Serialization Constant + private static final long serialVersionUID = -4536902356223894379L; -// Serialization Constant -private static final long serialVersionUID = -4536902356223894379L; - -/*************************************************************************/ - -/* - * Instance Variables - */ - -/** - * The font for this component. - * - * @see #getFont() - * @see #setFont(java.awt.Font) - * @serial the component's font. - */ + /** + * The font for this component. + * + * @see #getFont() + * @see #setFont(java.awt.Font) + * @serial the component's font. + */ private Font font; /** @@ -165,1160 +156,1133 @@ private static final long serialVersionUID = -4536902356223894379L; */ transient FocusListener focusListener; -/*************************************************************************/ - -/* - * Constructors - */ - -/** - * Default constructor for subclasses. - * - * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. - */ -public -MenuComponent() -{ - if (GraphicsEnvironment.isHeadless()) - throw new HeadlessException (); -} - -/*************************************************************************/ - -/* - * Instance Methods - */ + /** + * Default constructor for subclasses. + * + * @throws HeadlessException ff GraphicsEnvironment.isHeadless() is true + */ + public MenuComponent() + { + if (GraphicsEnvironment.isHeadless()) + throw new HeadlessException(); + } /** * Returns the font in use for this component. * - * @return The font for this component. - */ -public Font -getFont() -{ - if (font != null) - return font; - - if (parent != null) - return parent.getFont (); - - return null; -} - -/*************************************************************************/ - -/** - * Sets the font for this component to the specified font. - * - * @param font The new font for this component. - */ -public void -setFont(Font font) -{ - this.font = font; -} - -/*************************************************************************/ - -/** - * Returns the name of this component. - * - * @return The name of this component. - */ -public String -getName() -{ - return(name); -} - -/*************************************************************************/ - -/** - * Sets the name of this component to the specified name. - * - * @param name The new name of this component. - */ -public void -setName(String name) -{ - this.name = name; - nameExplicitlySet = true; -} - -/*************************************************************************/ - -/** - * Returns the parent of this component. - * - * @return The parent of this component. - */ -public MenuContainer -getParent() -{ - return(parent); -} - -/*************************************************************************/ - -// Sets the parent of this component. -final void -setParent(MenuContainer parent) -{ - this.parent = parent; -} - -/*************************************************************************/ - -/** - * Returns the native windowing system peer for this component. - * - * @return The peer for this component. - * - * @deprecated - */ -public MenuComponentPeer -getPeer() -{ - return(peer); -} - -/*************************************************************************/ - -// Sets the peer for this component. -final void -setPeer(MenuComponentPeer peer) -{ - this.peer = peer; -} - -/*************************************************************************/ - -/** - * Destroys this component's native peer - */ -public void -removeNotify() -{ - if (peer != null) - peer.dispose(); - peer = null; -} - -/*************************************************************************/ - -/** - * Returns the toolkit in use for this component. - * - * @return The toolkit for this component. - */ -final Toolkit -getToolkit() -{ - return(toolkit); -} - -/*************************************************************************/ - -/** - * Returns the object used for synchronization locks on this component - * when performing tree and layout functions. - * - * @return The synchronization lock for this component. - */ -protected final Object -getTreeLock() -{ - return(tree_lock); -} - -/*************************************************************************/ - -// The sync lock object for this component. -final void -setTreeLock(Object tree_lock) -{ - this.tree_lock = tree_lock; -} - -/*************************************************************************/ - -/** - * AWT 1.0 event dispatcher. - * - * @deprecated Deprecated in favor of <code>dispatchEvent()</code>. - * @return true if the event was dispatched, false otherwise. - */ -public boolean -postEvent(Event event) -{ - // This is overridden by subclasses that support events. - return false; -} -/*************************************************************************/ - -/** - * Sends this event to this component or a subcomponent for processing. - * - * @param event The event to dispatch - */ -public final void dispatchEvent(AWTEvent event) -{ - // See comment in Component.dispatchEvent(). - dispatchEventImpl(event); -} - - -/** - * Implementation of dispatchEvent. Allows trusted package classes - * to dispatch additional events first. This implementation first - * translates <code>event</code> to an AWT 1.0 event and sends the - * result to {@link #postEvent}. The event is then - * passed on to {@link #processEvent} for local processing. - * - * @param event the event to dispatch. - */ -void dispatchEventImpl(AWTEvent event) -{ - Event oldStyleEvent; - - // This is overridden by subclasses that support events. - /* Convert AWT 1.1 event to AWT 1.0 event */ - oldStyleEvent = Component.translateEvent(event); - if (oldStyleEvent != null) - { - postEvent(oldStyleEvent); - } - /* Do local processing */ - processEvent(event); -} - -/*************************************************************************/ - -/** - * Processes the specified event. In this class, this method simply - * calls one of the more specific event handlers. - * - * @param event The event to process. - */ -protected void -processEvent(AWTEvent event) -{ - /* - Pass a focus event to the focus listener for - the accessibility context. - */ - if (event instanceof FocusEvent) - { - if (focusListener != null) - { - switch (event.id) - { - case FocusEvent.FOCUS_GAINED: - focusListener.focusGained((FocusEvent) event); - break; - case FocusEvent.FOCUS_LOST: - focusListener.focusLost((FocusEvent) event); - break; - } - } - } -} - -/*************************************************************************/ - -/** - * Returns a string representation of this component. - * - * @return A string representation of this component + * @return the font for this component */ -public String -toString() -{ - return this.getClass().getName() + "[" + paramString() + "]"; -} - -/*************************************************************************/ - -/** - * Returns a debugging string for this component - */ -protected String -paramString() -{ - return "name=" + getName(); -} - -/** - * Gets the AccessibleContext associated with this <code>MenuComponent</code>. - * As an abstract class, we return null. Concrete subclasses should return - * their implementation of the accessibility context. - * - * @return null. - */ - -public AccessibleContext getAccessibleContext() -{ - return null; -} + public Font getFont() + { + if (font != null) + return font; -/** - * This class provides a base for the accessibility support of menu - * components. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ -protected abstract class AccessibleAWTMenuComponent - extends AccessibleContext - implements Serializable, AccessibleComponent, AccessibleSelection -{ + if (parent != null) + return parent.getFont(); - /** - * Compatible with JDK 1.4.2 revision 5 - */ - private static final long serialVersionUID = -4269533416223798698L; - - /** - * This is the default constructor. It should be called by - * concrete subclasses to ensure necessary groundwork is completed. - */ - protected AccessibleAWTMenuComponent() - { + return null; } /** - * Replaces or supplements the component's selection with the - * <code>Accessible</code> child at the supplied index. If - * the component supports multiple selection, the child is - * added to the current selection. Otherwise, the current - * selection becomes the specified child. If the child is - * already selected, nothing happens. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. + * Sets the font for this component to the specified font. * - * @param index the index of the specified child within a - * zero-based list of the component's children. + * @param font the new font for this component */ - public void addAccessibleSelection(int index) + public void setFont(Font font) { - /* Subclasses with children should implement this */ + this.font = font; } /** - * Registers the specified focus listener to receive - * focus events from this component. + * Returns the name of this component. * - * @param listener the new focus listener. + * @return the name of this component */ - public void addFocusListener(FocusListener listener) + public String getName() { - /* - * Chain the new focus listener to the existing chain - * of focus listeners. Each new focus listener is - * coupled via multicasting to the existing chain. - */ - focusListener = AWTEventMulticaster.add(focusListener, listener); + return name; } /** - * Clears the component's current selection. Following - * the calling of this method, no children of the component - * will be selected. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. - */ - public void clearAccessibleSelection() - { - } - - /** - * Returns true if the specified point lies within the - * component. The supplied co-ordinates are assumed to - * be relative to the co-ordinate system of the component - * itself. Thus, the point (0,0) is the upper left corner - * of this component. - * <br /> - * <br /> - * Please note that this method depends on a correctly implemented - * version of the <code>getBounds()</code> method. Subclasses - * must provide the bounding rectangle via <code>getBounds()</code> - * in order for this method to work. + * Sets the name of this component to the specified name. * - * @param point the point to check against this component. - * @return true if the point is within this component. - * @see #getBounds() + * @param name the new name of this component */ - public boolean contains(Point point) + public void setName(String name) { - /* - We can simply return the result of a - test for containment in the bounding rectangle - */ - return getBounds().contains(point); + this.name = name; + nameExplicitlySet = true; } /** - * Returns the <code>Accessible</code> child of this component present - * at the specified point. The supplied co-ordinates are - * assumed to be relative to the co-ordinate system of this - * component (the parent of any returned accessible). Thus, - * the point (0,0) is the upper left corner of this menu - * component. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. + * Returns the parent of this component. * - * @param point the point at which the returned accessible - * is located. - * @return null. + * @return the parent of this component */ - public Accessible getAccessibleAt(Point point) + public MenuContainer getParent() { - return null; - } + return parent; + } /** - * Returns the <code>Accessible</code> child at the supplied - * index within the list of children of this component. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. + * Sets the parent of this component. * - * @param index the index of the <code>Accessible</code> child - * to retrieve. - * @return null. + * @param parent the parent to set */ - public Accessible getAccessibleChild(int index) + final void setParent(MenuContainer parent) { - return null; + this.parent = parent; } /** - * Returns the number of children of this component which - * implement the <code>Accessible</code> interface. If - * all children of this component are accessible, then - * the returned value will be the same as the number of - * children. - * <br /> - * <br /> + * Returns the native windowing system peer for this component. + * + * @return the peer for this component * - * @return 0. + * @deprecated */ - public int getAccessibleChildrenCount() + public MenuComponentPeer getPeer() { - return 0; + return peer; } /** - * Retrieves the <code>AccessibleComponent</code> associated - * with this accessible context and its component. As the - * context itself implements <code>AccessibleComponent</code>, - * this is the return value. + * Sets the peer for this component. * - * @return the context itself. + * @param peer the peer to set */ - public AccessibleComponent getAccessibleComponent() + final void setPeer(MenuComponentPeer peer) { - return this; + this.peer = peer; } /** - * Returns the accessible name for this menu component. This - * is the name given to the component, which may be null if - * not set using <code>setName()</code>. - * <br /> - * <br /> - * The name is not the most appropriate description of this - * object. Subclasses should preferably provide a more - * accurate description. For example, a File menu could - * have the description `Lists commands related to the - * file system'. - * - * @return a description of the component. Currently, - * this is just the contents of the name property. - * @see MenuComponent#setName(String) + * Destroys this component's native peer */ - public String getAccessibleDescription() + public void removeNotify() { - return MenuComponent.this.getName(); + if (peer != null) + peer.dispose(); + peer = null; } /** - * Retrieves the index of this component within its parent. - * If no parent exists, -1 is returned. + * Returns the toolkit in use for this component. * - * @return -1 as the parent, a <code>MenuContainer</code> - * is not <code>Accessible</code>. + * @return the toolkit for this component */ - public int getAccessibleIndexInParent() + final Toolkit getToolkit() { - return -1; + return toolkit; } /** - * Returns the accessible name of this component. This - * is the name given to the component, which may be null if - * not set using <code>setName()</code>. - * <br /> - * <br /> - * The name property is not the most suitable string to return - * for this method. The string should be localized, and - * relevant to the operation of the component. For example, - * it could be the text of a menu item. However, this can - * not be used at this level of abstraction, so it is the - * responsibility of subclasses to provide a more appropriate - * name. + * Returns the object used for synchronization locks on this component + * when performing tree and layout functions. * - * @return a localized name for this component. Currently, this - * is just the contents of the name property. - * @see MenuComponent#setName(String) + * @return the synchronization lock for this component */ - public String getAccessibleName() + protected final Object getTreeLock() { - return MenuComponent.this.getName(); + return tree_lock; } /** - * Returns the <code>Accessible</code> parent of this component. - * As the parent of a <code>MenuComponent</code> is a - * <code>MenuContainer</code>, which doesn't implement - * <code>Accessible</code>, this method returns null. + * Sets the sync lock object for this component. * - * @return null. + * @param treeLock the sync lock to set */ - public Accessible getAccessibleParent() + final void setTreeLock(Object treeLock) { - return null; + this.tree_lock = treeLock; } /** - * Returns the accessible role of this component. - * <br /> - * <br /> - * The abstract implementation of this method returns - * <code>AccessibleRole.AWT_COMPONENT</code>, - * as the abstract component has no specific role. This - * method should be overridden by concrete subclasses, so - * as to return an appropriate role for the component. + * AWT 1.0 event dispatcher. * - * @return <code>AccessibleRole.AWT_COMPONENT</code>. + * @return true if the event was dispatched, false otherwise + * + * @deprecated Deprecated in favor of <code>dispatchEvent()</code>. */ - public AccessibleRole getAccessibleRole() + public boolean + postEvent(Event event) { - return AccessibleRole.AWT_COMPONENT; + boolean retVal = false; + MenuContainer parent = getParent(); + if (parent != null) + retVal = parent.postEvent(event); + + return retVal; } /** - * Retrieves the <code>AccessibleSelection</code> associated - * with this accessible context and its component. As the - * context itself implements <code>AccessibleSelection</code>, - * this is the return value. + * Sends this event to this component or a subcomponent for processing. * - * @return the context itself. + * @param event The event to dispatch */ - public AccessibleSelection getAccessibleSelection() + public final void dispatchEvent(AWTEvent event) { - return this; + // Convert AWT 1.1 event to AWT 1.0 event. + Event oldStyleEvent = Component.translateEvent(event); + if (oldStyleEvent != null) + { + postEvent(oldStyleEvent); + } + + // See comment in Component.dispatchEvent(). + dispatchEventImpl(event); } /** - * Retrieves the <code>Accessible</code> selected child - * at the specified index. If there are no selected children - * or the index is outside the range of selected children, - * null is returned. Please note that the index refers - * to the index of the child in the list of <strong>selected - * children</strong>, and not the index of the child in - * the list of all <code>Accessible</code> children. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. + * Implementation of dispatchEvent. Allows trusted package classes + * to dispatch additional events first. This implementation first + * translates <code>event</code> to an AWT 1.0 event and sends the + * result to {@link #postEvent}. The event is then + * passed on to {@link #processEvent} for local processing. * - * @param index the index of the selected <code>Accessible</code> - * child. + * @param event the event to dispatch */ - public Accessible getAccessibleSelection(int index) + void dispatchEventImpl(AWTEvent event) { - return null; + // Do local processing. + processEvent(event); } /** - * Returns a count of the number of <code>Accessible</code> - * children of this component which are currently selected. - * If there are no children currently selected, 0 is returned. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. - * - * @return 0. + * Processes the specified event. In this class, this method simply + * calls one of the more specific event handlers. + * + * @param event the event to process */ - public int getAccessibleSelectionCount() + protected void processEvent(AWTEvent event) { - return 0; + // Pass a focus event to the focus listener for + // the accessibility context. + if (event instanceof FocusEvent) + { + if (focusListener != null) + { + switch (event.id) + { + case FocusEvent.FOCUS_GAINED: + focusListener.focusGained((FocusEvent) event); + break; + case FocusEvent.FOCUS_LOST: + focusListener.focusLost((FocusEvent) event); + break; + } + } + } } /** - * Retrieves the current state of this component - * in an accessible form. For example, a given component - * may be visible, selected, disabled, etc. - * <br /> - * <br /> - * As this class tells us virtually nothing about the component, - * except for its name and font, no state information can be - * provided. This implementation thus returns an empty - * state set, and it is left to concrete subclasses to provide - * a more acceptable and relevant state set. Changes to these - * properties also need to be handled using - * <code>PropertyChangeListener</code>s. + * Returns a string representation of this component. * - * @return an empty <code>AccessibleStateSet</code>. + * @return a string representation of this component */ - public AccessibleStateSet getAccessibleStateSet() + public String toString() { - return new AccessibleStateSet(); + return getClass().getName() + "[" + paramString() + "]"; } /** - * Returns the background color of the component, or null - * if this property is unsupported. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply returns the - * default system background color used for rendering menus. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. - * - * @return the default system background color for menus. - * @see #setBackground(java.awt.Color) + * Returns a debugging string for this component */ - public Color getBackground() + protected String paramString() { - return SystemColor.menu; + return "name=" + getName(); } /** - * Returns a <code>Rectangle</code> which represents the - * bounds of this component. The returned rectangle has the - * height and width of the component's bounds, and is positioned - * at a location relative to this component's parent, the - * <code>MenuContainer</code>. null is returned if bounds - * are not supported by the component. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply returns null. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. + * Gets the AccessibleContext associated with this <code>MenuComponent</code>. + * As an abstract class, we return null. Concrete subclasses should return + * their implementation of the accessibility context. * - * @return null. - * @see #setBounds(java.awt.Rectangle) + * @return null */ - public Rectangle getBounds() + public AccessibleContext getAccessibleContext() { return null; } /** - * Returns the <code>Cursor</code> displayed when the pointer - * is positioned over this component. Alternatively, null - * is returned if the component doesn't support the cursor - * property. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply returns the default - * system cursor. Concrete subclasses which handle the drawing - * of an onscreen menu component may override this method and provide - * the appropriate information. + * This class provides a base for the accessibility support of menu + * components. * - * @return the default system cursor. - * @see #setCursor(java.awt.Cursor) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) */ - public Cursor getCursor() + protected abstract class AccessibleAWTMenuComponent + extends AccessibleContext + implements Serializable, AccessibleComponent, AccessibleSelection { - return Cursor.getDefaultCursor(); - } - /** - * Returns the <code>Font</code> used for text created by this component. - * - * @return the current font. - * @see #setFont(java.awt.Font) - */ - public Font getFont() - { - return MenuComponent.this.getFont(); - } + /** + * Compatible with JDK 1.4.2 revision 5 + */ + private static final long serialVersionUID = -4269533416223798698L; - /** - * Retrieves information on the rendering and metrics of the supplied - * font. If font metrics are not supported by this component, null - * is returned. - * <br /> - * <br /> - * The abstract implementation of this method simply uses the toolkit - * to obtain the <code>FontMetrics</code>. Concrete subclasses may - * find it more efficient to invoke their peer class directly, if one - * is available. - * - * @param font the font about which to retrieve rendering and metric - * information. - * @return the metrics of the given font, as provided by the system - * toolkit. - * @throws NullPointerException if the supplied font was null. - */ - public FontMetrics getFontMetrics(Font font) - { - return MenuComponent.this.getToolkit().getFontMetrics(font); - } + /** + * This is the default constructor. It should be called by + * concrete subclasses to ensure necessary groundwork is completed. + */ + protected AccessibleAWTMenuComponent() + { + // Nothing to do here. + } - /** - * Returns the foreground color of the component, or null - * if this property is unsupported. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply returns the - * default system text color used for rendering menus. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. - * - * @return the default system text color for menus. - * @see #setForeground(java.awt.Color) - */ - public Color getForeground() - { - return SystemColor.menuText; - } + /** + * Replaces or supplements the component's selection with the + * <code>Accessible</code> child at the supplied index. If + * the component supports multiple selection, the child is + * added to the current selection. Otherwise, the current + * selection becomes the specified child. If the child is + * already selected, nothing happens. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @param index the index of the specified child within a + * zero-based list of the component's children + */ + public void addAccessibleSelection(int index) + { + // Subclasses with children should implement this. + } - /** - * Returns the locale currently in use by this component. - * <br /> - * <br /> - * This abstract class has no property relating to the - * locale used by the component, so this method simply - * returns the default locale for the current instance - * of the Java Virtual Machine (JVM). Concrete subclasses - * which maintain such a property should override this method - * and provide the locale information more accurately. - * - * @return the default locale for this JVM instance. - */ - public Locale getLocale() - { - return Locale.getDefault(); - } + /** + * Registers the specified focus listener to receive + * focus events from this component. + * + * @param listener the new focus listener + */ + public void addFocusListener(FocusListener listener) + { + // Chain the new focus listener to the existing chain + // of focus listeners. Each new focus listener is + // coupled via multicasting to the existing chain. + focusListener = AWTEventMulticaster.add(focusListener, listener); + } - /** - * Returns the location of the component, with co-ordinates - * relative to the parent component and using the co-ordinate - * space of the screen. Thus, the point (0,0) is the upper - * left corner of the parent component. - * <br /> - * <br /> - * Please note that this method depends on a correctly implemented - * version of the <code>getBounds()</code> method. Subclasses - * must provide the bounding rectangle via <code>getBounds()</code> - * in order for this method to work. - * - * @return the location of the component, relative to its parent. - * @see #setLocation(java.awt.Point) - */ - public Point getLocation() - { - /* Simply return the location of the bounding rectangle */ - return getBounds().getLocation(); - } + /** + * Clears the component's current selection. Following + * the calling of this method, no children of the component + * will be selected. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + */ + public void clearAccessibleSelection() + { + // Nothing to do here. + } - /** - * Returns the location of the component, with co-ordinates - * relative to the screen. Thus, the point (0,0) is the upper - * left corner of the screen. null is returned if the component - * is either not on screen or if this property is unsupported. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply returns null. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. - * - * @return the location of the component, relative to the screen. - */ - public Point getLocationOnScreen() - { - return null; - } + /** + * Returns true if the specified point lies within the + * component. The supplied co-ordinates are assumed to + * be relative to the co-ordinate system of the component + * itself. Thus, the point (0,0) is the upper left corner + * of this component. + * <br /> + * <br /> + * Please note that this method depends on a correctly implemented + * version of the <code>getBounds()</code> method. Subclasses + * must provide the bounding rectangle via <code>getBounds()</code> + * in order for this method to work. + * + * @param point the point to check against this component + * @return true if the point is within this component + * @see #getBounds() + */ + public boolean contains(Point point) + { + // We can simply return the result of a + // test for containment in the bounding rectangle. + return getBounds().contains(point); + } - /** - * Returns the size of the component. - * <br /> - * <br /> - * Please note that this method depends on a correctly implemented - * version of the <code>getBounds()</code> method. Subclasses - * must provide the bounding rectangle via <code>getBounds()</code> - * in order for this method to work. - * - * @return the size of the component. - * @see #setSize(java.awt.Dimension) - */ - public Dimension getSize() - { - /* Simply return the size of the bounding rectangle */ - return getBounds().getSize(); - } + /** + * Returns the <code>Accessible</code> child of this component present + * at the specified point. The supplied co-ordinates are + * assumed to be relative to the co-ordinate system of this + * component (the parent of any returned accessible). Thus, + * the point (0,0) is the upper left corner of this menu + * component. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @param point the point at which the returned accessible + * is located + * @return null + */ + public Accessible getAccessibleAt(Point point) + { + return null; + } - /** - * Returns true if the accessible child specified by the supplied index - * is currently selected. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. - * - * @param index the index of the accessible child to check for selection. - * @return false. - */ - public boolean isAccessibleChildSelected(int index) - { - return false; - } + /** + * Returns the <code>Accessible</code> child at the supplied + * index within the list of children of this component. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @param index the index of the <code>Accessible</code> child + * to retrieve + * + * @return null + */ + public Accessible getAccessibleChild(int index) + { + return null; + } - /** - * Returns true if this component is currently enabled. - * <br /> - * <br /> - * As this abstract component has no properties related to - * its enabled or disabled state, the implementation of this - * method is left to subclasses. - * - * @return false. - * @see #setEnabled(boolean) - */ - public boolean isEnabled() - { - return false; - } + /** + * Returns the number of children of this component which + * implement the <code>Accessible</code> interface. If + * all children of this component are accessible, then + * the returned value will be the same as the number of + * children. + * <br /> + * <br /> + * + * @return 0 + */ + public int getAccessibleChildrenCount() + { + return 0; + } - /** - * Returns true if this component is included in the traversal - * of the current focus from one component to the other. - * <br /> - * <br /> - * As this abstract component has no properties related to - * its ability to accept the focus, the implementation of this - * method is left to subclasses. - * - * @return false. - */ - public boolean isFocusTraversable() - { - return false; - } + /** + * Retrieves the <code>AccessibleComponent</code> associated + * with this accessible context and its component. As the + * context itself implements <code>AccessibleComponent</code>, + * this is the return value. + * + * @return the context itself + */ + public AccessibleComponent getAccessibleComponent() + { + return this; + } - /** - * Returns true if the component is being shown on screen. - * A component is determined to be shown if it is visible, - * and each parent component is also visible. Please note - * that, even when a component is showing, it may still be - * obscured by other components in front. This method only - * determines if the component is being drawn on the screen. - * <br /> - * <br /> - * As this abstract component and its parent have no properties - * relating to visibility, the implementation of this method is - * left to subclasses. - * - * @return false. - * @see #isVisible() - */ - public boolean isShowing() - { - return false; - } + /** + * Returns the accessible name for this menu component. This + * is the name given to the component, which may be null if + * not set using <code>setName()</code>. + * <br /> + * <br /> + * The name is not the most appropriate description of this + * object. Subclasses should preferably provide a more + * accurate description. For example, a File menu could + * have the description `Lists commands related to the + * file system'. + * + * @return a description of the component. Currently, + * this is just the contents of the name property + * + * @see MenuComponent#setName(String) + */ + public String getAccessibleDescription() + { + return MenuComponent.this.getName(); + } - /** - * Returns true if the component is visible. A component may - * be visible but not drawn on the screen if one of its parent - * components is not visible. To determine if the component is - * actually drawn on screen, <code>isShowing()</code> should be - * used. - * <br /> - * <br /> - * As this abstract component has no properties relating to its - * visibility, the implementation of this method is left to subclasses. - * - * @return false. - * @see #isShowing() - * @see #setVisible(boolean) - */ - public boolean isVisible() - { - return false; - } + /** + * Retrieves the index of this component within its parent. + * If no parent exists, -1 is returned. + * + * @return -1 as the parent, a <code>MenuContainer</code> + * is not <code>Accessible</code> + */ + public int getAccessibleIndexInParent() + { + return -1; + } - /** - * Removes the accessible child specified by the supplied index from - * the list of currently selected children. If the child specified - * is not selected, nothing happens. - * <br /> - * <br /> - * As the existence of children can not be determined from - * this abstract class, the implementation of this method - * is left to subclasses. - * - * @param index the index of the <code>Accessible</code> child. - */ - public void removeAccessibleSelection(int index) - { - /* Subclasses with children should implement this */ - } + /** + * Returns the accessible name of this component. This + * is the name given to the component, which may be null if + * not set using <code>setName()</code>. + * <br /> + * <br /> + * The name property is not the most suitable string to return + * for this method. The string should be localized, and + * relevant to the operation of the component. For example, + * it could be the text of a menu item. However, this can + * not be used at this level of abstraction, so it is the + * responsibility of subclasses to provide a more appropriate + * name. + * + * @return a localized name for this component. Currently, this + * is just the contents of the name property + * + * @see MenuComponent#setName(String) + */ + public String getAccessibleName() + { + return MenuComponent.this.getName(); + } - /** - * Removes the specified focus listener from the list of registered - * focus listeners for this component. - * - * @param listener the listener to remove. - */ - public void removeFocusListener(FocusListener listener) - { - /* Remove the focus listener from the chain */ - focusListener = AWTEventMulticaster.remove(focusListener, listener); - } + /** + * Returns the <code>Accessible</code> parent of this component. + * As the parent of a <code>MenuComponent</code> is a + * <code>MenuContainer</code>, which doesn't implement + * <code>Accessible</code>, this method returns null. + * + * @return null + */ + public Accessible getAccessibleParent() + { + return null; + } - /** - * Requests that this component gains focus. This depends on the - * component being focus traversable. - * <br /> - * <br /> - * As this abstract component has no properties relating to its - * focus traversability, or access to a peer with request focusing - * abilities, the implementation of this method is left to subclasses. - */ - public void requestFocus() - { - /* Ignored */ - } + /** + * Returns the accessible role of this component. + * <br /> + * <br /> + * The abstract implementation of this method returns + * <code>AccessibleRole.AWT_COMPONENT</code>, + * as the abstract component has no specific role. This + * method should be overridden by concrete subclasses, so + * as to return an appropriate role for the component. + * + * @return <code>AccessibleRole.AWT_COMPONENT</code> + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.AWT_COMPONENT; + } - /** - * Selects all <code>Accessible</code> children of this component which - * it is possible to select. The component needs to support multiple - * selections. - * <br /> - * <br /> - * This abstract component provides a simplistic implementation of this - * method, which ignores the ability of the component to support multiple - * selections and simply uses <code>addAccessibleSelection</code> to - * add each <code>Accessible</code> child to the selection. The last - * <code>Accessible</code> component is thus selected for components - * which don't support multiple selections. Concrete implementations should - * override this with a more appopriate and efficient implementation, which - * properly takes into account the ability of the component to support multiple - * selections. - */ - public void selectAllAccessibleSelection() - { - /* Simply call addAccessibleSelection() on all accessible children */ - for (int a = 0; a < getAccessibleChildrenCount(); ++a) - { - addAccessibleSelection(a); - } - } + /** + * Retrieves the <code>AccessibleSelection</code> associated + * with this accessible context and its component. As the + * context itself implements <code>AccessibleSelection</code>, + * this is the return value. + * + * @return the context itself + */ + public AccessibleSelection getAccessibleSelection() + { + return this; + } - /** - * Sets the background color of the component to that specified. - * Unspecified behaviour occurs when null is given as the new - * background color. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply ignores the supplied - * color and continues to use the default system color. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. - * - * @param color the new color to use for the background. - * @see #getBackground() - */ - public void setBackground(Color color) - { - /* Ignored */ - } + /** + * Retrieves the <code>Accessible</code> selected child + * at the specified index. If there are no selected children + * or the index is outside the range of selected children, + * null is returned. Please note that the index refers + * to the index of the child in the list of <strong>selected + * children</strong>, and not the index of the child in + * the list of all <code>Accessible</code> children. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @param index the index of the selected <code>Accessible</code> + * child + */ + public Accessible getAccessibleSelection(int index) + { + return null; + } - /** - * Sets the height and width of the component, and its position - * relative to this component's parent, to the values specified - * by the supplied rectangle. Unspecified behaviour occurs when - * null is given as the new bounds. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply ignores the new - * rectangle and continues to return null from <code>getBounds()</code>. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. - * - * @param rectangle a rectangle which specifies the new bounds of - * the component. - * @see #getBounds() - */ - public void setBounds(Rectangle rectangle) - { - /* Ignored */ - } + /** + * Returns a count of the number of <code>Accessible</code> + * children of this component which are currently selected. + * If there are no children currently selected, 0 is returned. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @return 0 + */ + public int getAccessibleSelectionCount() + { + return 0; + } - /** - * Sets the <code>Cursor</code> used when the pointer is positioned over the - * component. Unspecified behaviour occurs when null is given as the new - * cursor. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply ignores the new cursor - * and continues to return the default system cursor. Concrete - * subclasses which handle the drawing of an onscreen menu component - * may override this method and provide the appropriate information. - * - * @param cursor the new cursor to use. - * @see #getCursor() - */ - public void setCursor(Cursor cursor) - { - /* Ignored */ - } + /** + * Retrieves the current state of this component + * in an accessible form. For example, a given component + * may be visible, selected, disabled, etc. + * <br /> + * <br /> + * As this class tells us virtually nothing about the component, + * except for its name and font, no state information can be + * provided. This implementation thus returns an empty + * state set, and it is left to concrete subclasses to provide + * a more acceptable and relevant state set. Changes to these + * properties also need to be handled using + * <code>PropertyChangeListener</code>s. + * + * @return an empty <code>AccessibleStateSet</code> + */ + public AccessibleStateSet getAccessibleStateSet() + { + return new AccessibleStateSet(); + } - /** - * Sets the enabled/disabled state of this component. - * <br /> - * <br /> - * As this abstract component has no properties related to - * its enabled or disabled state, the implementation of this - * method is left to subclasses. - * - * @param enabled true if the component should be enabled, - * false otherwise. - * @see #isEnabled() - */ - public void setEnabled(boolean enabled) - { - /* Ignored */ - } + /** + * Returns the background color of the component, or null + * if this property is unsupported. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply returns the + * default system background color used for rendering menus. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @return the default system background color for menus + * + * @see #setBackground(java.awt.Color) + */ + public Color getBackground() + { + return SystemColor.menu; + } - /** - * Sets the <code>Font</code> used for text created by this component. - * Unspecified behaviour occurs when null is given as the new - * font. - * - * @param font the new font to use for text. - * @see #getFont() - */ - public void setFont(Font font) - { - /* Call the method of the enclosing component */ - MenuComponent.this.setFont(font); - } + /** + * Returns a <code>Rectangle</code> which represents the + * bounds of this component. The returned rectangle has the + * height and width of the component's bounds, and is positioned + * at a location relative to this component's parent, the + * <code>MenuContainer</code>. null is returned if bounds + * are not supported by the component. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply returns null. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @return null + * + * @see #setBounds(java.awt.Rectangle) + */ + public Rectangle getBounds() + { + return null; + } - /** - * Sets the foreground color of the component to that specified. - * Unspecified behaviour occurs when null is given as the new - * background color. - * <br /> - * <br /> - * This abstract class knows nothing about how the component - * is drawn on screen, so this method simply ignores the supplied - * color and continues to return the default system text color used - * for rendering menus. - * Concrete subclasses which handle the drawing of an onscreen - * menu component should override this method and provide - * the appropriate information. - * - * @param color the new foreground color. - * @see #getForeground() - */ - public void setForeground(Color color) - { - /* Ignored */ - } + /** + * Returns the <code>Cursor</code> displayed when the pointer + * is positioned over this component. Alternatively, null + * is returned if the component doesn't support the cursor + * property. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply returns the default + * system cursor. Concrete subclasses which handle the drawing + * of an onscreen menu component may override this method and provide + * the appropriate information. + * + * @return the default system cursor + * + * @see #setCursor(java.awt.Cursor) + */ + public Cursor getCursor() + { + return Cursor.getDefaultCursor(); + } - /** - * Sets the location of the component, with co-ordinates - * relative to the parent component and using the co-ordinate - * space of the screen. Thus, the point (0,0) is the upper - * left corner of the parent component. - * <br /> - * <br /> - * Please note that this method depends on a correctly implemented - * version of the <code>getBounds()</code> method. Subclasses - * must provide the bounding rectangle via <code>getBounds()</code> - * in order for this method to work. - * - * @param point the location of the component, relative to its parent. - * @see #getLocation() - */ - public void setLocation(Point point) - { - getBounds().setLocation(point); - } + /** + * Returns the <code>Font</code> used for text created by this component. + * + * @return the current font + * + * @see #setFont(java.awt.Font) + */ + public Font getFont() + { + return MenuComponent.this.getFont(); + } - /** - * Sets the size of the component. - * <br /> - * <br /> - * Please note that this method depends on a correctly implemented - * version of the <code>getBounds()</code> method. Subclasses - * must provide the bounding rectangle via <code>getBounds()</code> - * in order for this method to work. - * - * @param size the new size of the component. - * @see #getSize() - */ - public void setSize(Dimension size) - { - getBounds().setSize(size); - } + /** + * Retrieves information on the rendering and metrics of the supplied + * font. If font metrics are not supported by this component, null + * is returned. + * <br /> + * <br /> + * The abstract implementation of this method simply uses the toolkit + * to obtain the <code>FontMetrics</code>. Concrete subclasses may + * find it more efficient to invoke their peer class directly, if one + * is available. + * + * @param font the font about which to retrieve rendering and metric + * information + * + * @return the metrics of the given font, as provided by the system + * toolkit + * + * @throws NullPointerException if the supplied font was null + */ + public FontMetrics getFontMetrics(Font font) + { + return MenuComponent.this.getToolkit().getFontMetrics(font); + } - /** - * Sets the visibility state of the component. A component may - * be visible but not drawn on the screen if one of its parent - * components is not visible. To determine if the component is - * actually drawn on screen, <code>isShowing()</code> should be - * used. - * <br /> - * <br /> - * As this abstract component has no properties relating to its - * visibility, the implementation of this method is left to subclasses. - * - * @param visibility the new visibility of the component -- true if - * the component is visible, false if not. - * @see #isShowing() - * @see #isVisible() - */ - public void setVisible(boolean visibility) - { - /* Ignored */ - } + /** + * Returns the foreground color of the component, or null + * if this property is unsupported. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply returns the + * default system text color used for rendering menus. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @return the default system text color for menus + * + * @see #setForeground(java.awt.Color) + */ + public Color getForeground() + { + return SystemColor.menuText; + } -} /* class AccessibleAWTMenuComponent */ - + /** + * Returns the locale currently in use by this component. + * <br /> + * <br /> + * This abstract class has no property relating to the + * locale used by the component, so this method simply + * returns the default locale for the current instance + * of the Java Virtual Machine (JVM). Concrete subclasses + * which maintain such a property should override this method + * and provide the locale information more accurately. + * + * @return the default locale for this JVM instance + */ + public Locale getLocale() + { + return Locale.getDefault(); + } + + /** + * Returns the location of the component, with co-ordinates + * relative to the parent component and using the co-ordinate + * space of the screen. Thus, the point (0,0) is the upper + * left corner of the parent component. + * <br /> + * <br /> + * Please note that this method depends on a correctly implemented + * version of the <code>getBounds()</code> method. Subclasses + * must provide the bounding rectangle via <code>getBounds()</code> + * in order for this method to work. + * + * @return the location of the component, relative to its parent + * + * @see #setLocation(java.awt.Point) + */ + public Point getLocation() + { + // Simply return the location of the bounding rectangle. + return getBounds().getLocation(); + } + + /** + * Returns the location of the component, with co-ordinates + * relative to the screen. Thus, the point (0,0) is the upper + * left corner of the screen. null is returned if the component + * is either not on screen or if this property is unsupported. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply returns null. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @return the location of the component, relative to the screen + */ + public Point getLocationOnScreen() + { + return null; + } + + /** + * Returns the size of the component. + * <br /> + * <br /> + * Please note that this method depends on a correctly implemented + * version of the <code>getBounds()</code> method. Subclasses + * must provide the bounding rectangle via <code>getBounds()</code> + * in order for this method to work. + * + * @return the size of the component + * + * @see #setSize(java.awt.Dimension) + */ + public Dimension getSize() + { + // Simply return the size of the bounding rectangle. + return getBounds().getSize(); + } + + /** + * Returns true if the accessible child specified by the supplied index + * is currently selected. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @param index the index of the accessible child to check for selection + * + * @return false + */ + public boolean isAccessibleChildSelected(int index) + { + return false; + } + + /** + * Returns true if this component is currently enabled. + * <br /> + * <br /> + * As this abstract component has no properties related to + * its enabled or disabled state, the implementation of this + * method is left to subclasses. + * + * @return false + * + * @see #setEnabled(boolean) + */ + public boolean isEnabled() + { + return false; + } -} // class MenuComponent + /** + * Returns true if this component is included in the traversal + * of the current focus from one component to the other. + * <br /> + * <br /> + * As this abstract component has no properties related to + * its ability to accept the focus, the implementation of this + * method is left to subclasses. + * + * @return false + */ + public boolean isFocusTraversable() + { + return false; + } + + /** + * Returns true if the component is being shown on screen. + * A component is determined to be shown if it is visible, + * and each parent component is also visible. Please note + * that, even when a component is showing, it may still be + * obscured by other components in front. This method only + * determines if the component is being drawn on the screen. + * <br /> + * <br /> + * As this abstract component and its parent have no properties + * relating to visibility, the implementation of this method is + * left to subclasses. + * + * @return false + * + * @see #isVisible() + */ + public boolean isShowing() + { + return false; + } + + /** + * Returns true if the component is visible. A component may + * be visible but not drawn on the screen if one of its parent + * components is not visible. To determine if the component is + * actually drawn on screen, <code>isShowing()</code> should be + * used. + * <br /> + * <br /> + * As this abstract component has no properties relating to its + * visibility, the implementation of this method is left to subclasses. + * + * @return false + * + * @see #isShowing() + * @see #setVisible(boolean) + */ + public boolean isVisible() + { + return false; + } + + /** + * Removes the accessible child specified by the supplied index from + * the list of currently selected children. If the child specified + * is not selected, nothing happens. + * <br /> + * <br /> + * As the existence of children can not be determined from + * this abstract class, the implementation of this method + * is left to subclasses. + * + * @param index the index of the <code>Accessible</code> child + */ + public void removeAccessibleSelection(int index) + { + // Subclasses with children should implement this. + } + + /** + * Removes the specified focus listener from the list of registered + * focus listeners for this component. + * + * @param listener the listener to remove + */ + public void removeFocusListener(FocusListener listener) + { + // Remove the focus listener from the chain. + focusListener = AWTEventMulticaster.remove(focusListener, listener); + } + + /** + * Requests that this component gains focus. This depends on the + * component being focus traversable. + * <br /> + * <br /> + * As this abstract component has no properties relating to its + * focus traversability, or access to a peer with request focusing + * abilities, the implementation of this method is left to subclasses. + */ + public void requestFocus() + { + // Ignored. + } + + /** + * Selects all <code>Accessible</code> children of this component which + * it is possible to select. The component needs to support multiple + * selections. + * <br /> + * <br /> + * This abstract component provides a simplistic implementation of this + * method, which ignores the ability of the component to support multiple + * selections and simply uses <code>addAccessibleSelection</code> to + * add each <code>Accessible</code> child to the selection. The last + * <code>Accessible</code> component is thus selected for components + * which don't support multiple selections. Concrete implementations should + * override this with a more appopriate and efficient implementation, which + * properly takes into account the ability of the component to support multiple + * selections. + */ + public void selectAllAccessibleSelection() + { + // Simply call addAccessibleSelection() on all accessible children. + for (int a = 0; a < getAccessibleChildrenCount(); ++a) + { + addAccessibleSelection(a); + } + } + + /** + * Sets the background color of the component to that specified. + * Unspecified behaviour occurs when null is given as the new + * background color. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply ignores the supplied + * color and continues to use the default system color. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @param color the new color to use for the background + * + * @see #getBackground() + */ + public void setBackground(Color color) + { + // Ignored. + } + + /** + * Sets the height and width of the component, and its position + * relative to this component's parent, to the values specified + * by the supplied rectangle. Unspecified behaviour occurs when + * null is given as the new bounds. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply ignores the new + * rectangle and continues to return null from <code>getBounds()</code>. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @param rectangle a rectangle which specifies the new bounds of + * the component + * + * @see #getBounds() + */ + public void setBounds(Rectangle rectangle) + { + // Ignored. + } + + /** + * Sets the <code>Cursor</code> used when the pointer is positioned over the + * component. Unspecified behaviour occurs when null is given as the new + * cursor. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply ignores the new cursor + * and continues to return the default system cursor. Concrete + * subclasses which handle the drawing of an onscreen menu component + * may override this method and provide the appropriate information. + * + * @param cursor the new cursor to use + * + * @see #getCursor() + */ + public void setCursor(Cursor cursor) + { + // Ignored. + } + + /** + * Sets the enabled/disabled state of this component. + * <br /> + * <br /> + * As this abstract component has no properties related to + * its enabled or disabled state, the implementation of this + * method is left to subclasses. + * + * @param enabled true if the component should be enabled, + * false otherwise + * + * @see #isEnabled() + */ + public void setEnabled(boolean enabled) + { + // Ignored. + } + + /** + * Sets the <code>Font</code> used for text created by this component. + * Unspecified behaviour occurs when null is given as the new + * font. + * + * @param font the new font to use for text. + * @see #getFont() + */ + public void setFont(Font font) + { + // Call the method of the enclosing component. + MenuComponent.this.setFont(font); + } + + /** + * Sets the foreground color of the component to that specified. + * Unspecified behaviour occurs when null is given as the new + * background color. + * <br /> + * <br /> + * This abstract class knows nothing about how the component + * is drawn on screen, so this method simply ignores the supplied + * color and continues to return the default system text color used + * for rendering menus. + * Concrete subclasses which handle the drawing of an onscreen + * menu component should override this method and provide + * the appropriate information. + * + * @param color the new foreground color + * + * @see #getForeground() + */ + public void setForeground(Color color) + { + // Ignored. + } + + /** + * Sets the location of the component, with co-ordinates + * relative to the parent component and using the co-ordinate + * space of the screen. Thus, the point (0,0) is the upper + * left corner of the parent component. + * <br /> + * <br /> + * Please note that this method depends on a correctly implemented + * version of the <code>getBounds()</code> method. Subclasses + * must provide the bounding rectangle via <code>getBounds()</code> + * in order for this method to work. + * + * @param point the location of the component, relative to its parent + * + * @see #getLocation() + */ + public void setLocation(Point point) + { + getBounds().setLocation(point); + } + + /** + * Sets the size of the component. + * <br /> + * <br /> + * Please note that this method depends on a correctly implemented + * version of the <code>getBounds()</code> method. Subclasses + * must provide the bounding rectangle via <code>getBounds()</code> + * in order for this method to work. + * + * @param size the new size of the component + * + * @see #getSize() + */ + public void setSize(Dimension size) + { + getBounds().setSize(size); + } + + /** + * Sets the visibility state of the component. A component may + * be visible but not drawn on the screen if one of its parent + * components is not visible. To determine if the component is + * actually drawn on screen, <code>isShowing()</code> should be + * used. + * <br /> + * <br /> + * As this abstract component has no properties relating to its + * visibility, the implementation of this method is left to subclasses. + * + * @param visibility the new visibility of the component -- true if + * the component is visible, false if not + * + * @see #isShowing() + * @see #isVisible() + */ + public void setVisible(boolean visibility) + { + // Ignored. + } + + } + +} diff --git a/libjava/classpath/java/awt/Scrollbar.java b/libjava/classpath/java/awt/Scrollbar.java index 6e506c78584..c0788370b21 100644 --- a/libjava/classpath/java/awt/Scrollbar.java +++ b/libjava/classpath/java/awt/Scrollbar.java @@ -1,5 +1,5 @@ /* Scrollbar.java -- AWT Scrollbar widget - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -593,13 +593,33 @@ public class Scrollbar extends Component implements Accessible, Adjustable adjustment_listeners.adjustmentValueChanged(event); } + /** + * Package private method to determine whether to call + * processEvent() or not. Will handle events from peer and update + * the current value. + */ void dispatchEventImpl(AWTEvent e) { if (e.id <= AdjustmentEvent.ADJUSTMENT_LAST - && e.id >= AdjustmentEvent.ADJUSTMENT_FIRST - && (adjustment_listeners != null - || (eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0)) - processEvent(e); + && e.id >= AdjustmentEvent.ADJUSTMENT_FIRST) + { + AdjustmentEvent ae = (AdjustmentEvent) e; + boolean adjusting = ae.getValueIsAdjusting(); + if (adjusting) + setValueIsAdjusting(true); + try + { + setValue(((AdjustmentEvent) e).getValue()); + if (adjustment_listeners != null + || (eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) + processEvent(e); + } + finally + { + if (adjusting) + setValueIsAdjusting(false); + } + } else super.dispatchEventImpl(e); } diff --git a/libjava/classpath/java/awt/TextField.java b/libjava/classpath/java/awt/TextField.java index 3302a2eff89..23d3d918ff4 100644 --- a/libjava/classpath/java/awt/TextField.java +++ b/libjava/classpath/java/awt/TextField.java @@ -397,6 +397,7 @@ addNotify() return; setPeer((ComponentPeer)getToolkit().createTextField(this)); + super.addNotify(); } /*************************************************************************/ diff --git a/libjava/classpath/java/awt/Toolkit.java b/libjava/classpath/java/awt/Toolkit.java index 2ca88b6f598..e2a4bc92ea7 100644 --- a/libjava/classpath/java/awt/Toolkit.java +++ b/libjava/classpath/java/awt/Toolkit.java @@ -39,6 +39,8 @@ exception statement from your version. */ package java.awt; +import gnu.java.awt.peer.GLightweightPeer; + import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; @@ -46,6 +48,7 @@ import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.event.AWTEventListener; +import java.awt.event.AWTEventListenerProxy; import java.awt.event.KeyEvent; import java.awt.im.InputMethodHighlight; import java.awt.image.ColorModel; @@ -76,6 +79,7 @@ import java.awt.peer.WindowPeer; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.net.URL; +import java.util.ArrayList; import java.util.Map; import java.util.Properties; @@ -114,10 +118,17 @@ public abstract class Toolkit = new PropertyChangeSupport(this); /** + * All registered AWTEventListener objects. This is package private, so the + * event queue can efficiently access this list. + */ + AWTEventListenerProxy[] awtEventListeners; + + /** * Default constructor for subclasses. */ public Toolkit() { + awtEventListeners = new AWTEventListenerProxy[0]; } /** @@ -349,7 +360,7 @@ public abstract class Toolkit */ protected LightweightPeer createComponent(Component target) { - return new gnu.java.awt.peer.GLightweightPeer (target); + return new GLightweightPeer(target); } /** @@ -462,7 +473,7 @@ public abstract class Toolkit */ public Insets getScreenInsets(GraphicsConfiguration gc) { - return null; + return new Insets(0, 0, 0, 0); } /** @@ -965,33 +976,230 @@ public abstract class Toolkit return desktopPropsSupport.getPropertyChangeListeners(name); } + /** + * Adds an AWTEventListener to this toolkit. This listener is informed about + * all events that pass the eventqueue that match the specified + * <code>evenMask</code>. The <code>eventMask</code> is an ORed combination + * of event masks as defined in {@link AWTEvent}. + * + * If a security manager is installed, it is asked first if an + * <code>AWTPermission("listenToAllAWTEvents")</code> is allowed. + * This may result in a <code>SecurityException</code> beeing thrown. + * + * It is not recommended to use this kind of notification for normal + * applications. It is intended solely for the purpose of debugging and to + * support special facilities. + * + * @param listener the listener to add + * @param eventMask the event mask of event types which the listener is + * interested in + * + * @since 1.2 + * + * @throws SecurityException if there is a <code>SecurityManager</code> that + * doesn't grant + * <code>AWTPermission("listenToAllAWTEvents")</code> + * + * @see #getAWTEventListeners() + * @see #getAWTEventListeners(long) + * @see #removeAWTEventListener(AWTEventListener) + */ public void addAWTEventListener(AWTEventListener listener, long eventMask) { - // SecurityManager s = System.getSecurityManager(); - // if (s != null) - // s.checkPermission(AWTPermission("listenToAllAWTEvents")); - // FIXME + // First we must check the security permissions. + SecurityManager s = System.getSecurityManager(); + if (s != null) + s.checkPermission(new AWTPermission("listenToAllAWTEvents")); + + // Go through the list and check if the requested listener is already + // registered. + boolean found = false; + for (int i = 0; i < awtEventListeners.length; ++i) + { + AWTEventListenerProxy proxy = awtEventListeners[i]; + if (proxy.getListener() == listener) + { + found = true; + // Modify the proxies event mask to include the new event mask. + AWTEventListenerProxy newProxy = + new AWTEventListenerProxy(proxy.getEventMask() | eventMask, + listener); + awtEventListeners[i] = newProxy; + break; + } + } + + // If that listener was not found, then add it. + if (! found) + { + AWTEventListenerProxy proxy = + new AWTEventListenerProxy(eventMask, listener); + AWTEventListenerProxy[] newArray = + new AWTEventListenerProxy[awtEventListeners.length + 1]; + System.arraycopy(awtEventListeners, 0, newArray, 0, + awtEventListeners.length); + newArray[newArray.length - 1] = proxy; + awtEventListeners = newArray; + } } + /** + * Removes an AWT event listener from this toolkit. This listener is no + * longer informed of any event types it was registered in. + * + * If a security manager is installed, it is asked first if an + * <code>AWTPermission("listenToAllAWTEvents")</code> is allowed. + * This may result in a <code>SecurityException</code> beeing thrown. + * + * It is not recommended to use this kind of notification for normal + * applications. It is intended solely for the purpose of debugging and to + * support special facilities. + * + * @param listener the listener to remove + * + * @throws SecurityException if there is a <code>SecurityManager</code> that + * doesn't grant + * <code>AWTPermission("listenToAllAWTEvents")</code> + * + * @since 1.2 + * + * @see #addAWTEventListener(AWTEventListener, long) + * @see #getAWTEventListeners() + * @see #getAWTEventListeners(long) + */ public void removeAWTEventListener(AWTEventListener listener) { - // FIXME + // First we must check the security permissions. + SecurityManager s = System.getSecurityManager(); + if (s != null) + s.checkPermission(new AWTPermission("listenToAllAWTEvents")); + + + // Find the index of the listener. + int index = -1; + for (int i = 0; i < awtEventListeners.length; ++i) + { + AWTEventListenerProxy proxy = awtEventListeners[i]; + if (proxy.getListener() == listener) + { + index = i; + break; + } + } + + // Copy over the arrays and leave out the removed element. + if (index != -1) + { + AWTEventListenerProxy[] newArray = + new AWTEventListenerProxy[awtEventListeners.length - 1]; + if (index > 0) + System.arraycopy(awtEventListeners, 0, newArray, 0, index); + if (index < awtEventListeners.length - 1) + System.arraycopy(awtEventListeners, index + 1, newArray, index, + awtEventListeners.length - index - 1); + awtEventListeners = newArray; + } } /** + * Returns all registered AWT event listeners. This method returns a copy of + * the listener array, so that application cannot trash the listener list. + * + * If a security manager is installed, it is asked first if an + * <code>AWTPermission("listenToAllAWTEvents")</code> is allowed. + * This may result in a <code>SecurityException</code> beeing thrown. + * + * It is not recommended to use this kind of notification for normal + * applications. It is intended solely for the purpose of debugging and to + * support special facilities. + * + * @return all registered AWT event listeners + * + * @throws SecurityException if there is a <code>SecurityManager</code> that + * doesn't grant + * <code>AWTPermission("listenToAllAWTEvents")</code> + * * @since 1.4 + * + * @see #addAWTEventListener(AWTEventListener, long) + * @see #removeAWTEventListener(AWTEventListener) + * @see #getAWTEventListeners(long) */ public AWTEventListener[] getAWTEventListeners() { - return null; + // First we must check the security permissions. + SecurityManager s = System.getSecurityManager(); + if (s != null) + s.checkPermission(new AWTPermission("listenToAllAWTEvents")); + + // Create a copy of the array. + AWTEventListener[] copy = new AWTEventListener[awtEventListeners.length]; + System.arraycopy(awtEventListeners, 0, copy, 0, awtEventListeners.length); + return copy; } /** + * Returns all registered AWT event listeners that listen for events with + * the specified <code>eventMask</code>. This method returns a copy of + * the listener array, so that application cannot trash the listener list. + * + * If a security manager is installed, it is asked first if an + * <code>AWTPermission("listenToAllAWTEvents")</code> is allowed. + * This may result in a <code>SecurityException</code> beeing thrown. + * + * It is not recommended to use this kind of notification for normal + * applications. It is intended solely for the purpose of debugging and to + * support special facilities. + * + * @param mask the event mask + * + * @throws SecurityException if there is a <code>SecurityManager</code> that + * doesn't grant + * <code>AWTPermission("listenToAllAWTEvents")</code> + * + * * @since 1.4 + * + * @see #addAWTEventListener(AWTEventListener, long) + * @see #removeAWTEventListener(AWTEventListener) + * @see #getAWTEventListeners() */ public AWTEventListener[] getAWTEventListeners(long mask) { - return null; + // First we must check the security permissions. + SecurityManager s = System.getSecurityManager(); + if (s != null) + s.checkPermission(new AWTPermission("listenToAllAWTEvents")); + + // Create a copy of the array with only the requested listeners in it. + ArrayList l = new ArrayList(awtEventListeners.length); + for (int i = 0; i < awtEventListeners.length; ++i) + { + if ((awtEventListeners[i].getEventMask() & mask) != 0) + l.add(awtEventListeners[i]); + } + + return (AWTEventListener[] ) l.toArray(new AWTEventListener[l.size()]); + } + + + /** + * Dispatches events to listeners registered to this Toolkit. This is called + * by {@link Component#dispatchEventImpl(AWTEvent)} in order to dispatch + * events globally. + * + * @param ev the event to dispatch + */ + void globalDispatchEvent(AWTEvent ev) + { + // We do not use the accessor methods here because they create new + // arrays each time. We must be very efficient, so we access this directly. + for (int i = 0; i < awtEventListeners.length; ++i) + { + AWTEventListenerProxy proxy = awtEventListeners[i]; + if ((proxy.getEventMask() & AWTEvent.eventIdToMask(ev.getID())) != 0) + proxy.eventDispatched(ev); + } } /** diff --git a/libjava/classpath/java/awt/Window.java b/libjava/classpath/java/awt/Window.java index f8a620daebd..71a8d388b30 100644 --- a/libjava/classpath/java/awt/Window.java +++ b/libjava/classpath/java/awt/Window.java @@ -281,50 +281,53 @@ public class Window extends Container implements Accessible public void show() { synchronized (getTreeLock()) - { - if (parent != null && !parent.isDisplayable()) - parent.addNotify(); - if (peer == null) - addNotify(); - - // Show visible owned windows. - Iterator e = ownedWindows.iterator(); - while(e.hasNext()) - { - Window w = (Window)(((Reference) e.next()).get()); - if (w != null) - { - if (w.isVisible()) - w.getPeer().setVisible(true); - } - else - // Remove null weak reference from ownedWindows. - // Unfortunately this can't be done in the Window's - // finalize method because there is no way to guarantee - // synchronous access to ownedWindows there. - e.remove(); - } - validate(); - super.show(); - toFront(); - - KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); - manager.setGlobalFocusedWindow (this); - - if (!shown) { - FocusTraversalPolicy policy = getFocusTraversalPolicy (); - Component initialFocusOwner = null; + if (parent != null && ! parent.isDisplayable()) + parent.addNotify(); + if (peer == null) + addNotify(); + + validate(); + if (visible) + toFront(); + else + { + super.show(); + // Show visible owned windows. + Iterator e = ownedWindows.iterator(); + while (e.hasNext()) + { + Window w = (Window) (((Reference) e.next()).get()); + if (w != null) + { + if (w.isVisible()) + w.getPeer().setVisible(true); + } + else + // Remove null weak reference from ownedWindows. + // Unfortunately this can't be done in the Window's + // finalize method because there is no way to guarantee + // synchronous access to ownedWindows there. + e.remove(); + } + } + KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + manager.setGlobalFocusedWindow(this); - if (policy != null) - initialFocusOwner = policy.getInitialComponent (this); + if (! shown) + { + FocusTraversalPolicy policy = getFocusTraversalPolicy(); + Component initialFocusOwner = null; - if (initialFocusOwner != null) - initialFocusOwner.requestFocusInWindow (); + if (policy != null) + initialFocusOwner = policy.getInitialComponent(this); - shown = true; + if (initialFocusOwner != null) + initialFocusOwner.requestFocusInWindow(); + + shown = true; + } } - } } public void hide() diff --git a/libjava/classpath/java/awt/datatransfer/DataFlavor.java b/libjava/classpath/java/awt/datatransfer/DataFlavor.java index 32bf4d6cf37..788ae6d6a52 100644 --- a/libjava/classpath/java/awt/datatransfer/DataFlavor.java +++ b/libjava/classpath/java/awt/datatransfer/DataFlavor.java @@ -157,38 +157,42 @@ public class DataFlavor implements java.io.Externalizable, Cloneable ClassLoader classLoader) throws ClassNotFoundException { + // Bootstrap try { - return(Class.forName(className)); + return Class.forName(className); } - catch(Exception e) { ; } - // Commented out for Java 1.1 - /* - try + catch(ClassNotFoundException cnfe) { - return(className.getClass().getClassLoader().findClass(className)); + // Ignored. } - catch(Exception e) { ; } + // System try { - return(ClassLoader.getSystemClassLoader().findClass(className)); + ClassLoader loader = ClassLoader.getSystemClassLoader(); + return Class.forName(className, true, loader); } - catch(Exception e) { ; } - */ - - // FIXME: What is the context class loader? - /* + catch(ClassNotFoundException cnfe) + { + // Ignored. + } + + // Context try { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + return Class.forName(className, true, loader); } - catch(Exception e) { ; } - */ - + catch(ClassNotFoundException cnfe) + { + // Ignored. + } + if (classLoader != null) - return(classLoader.loadClass(className)); - else - throw new ClassNotFoundException(className); + return Class.forName(className, true, classLoader); + + throw new ClassNotFoundException(className); } private static Class getRepresentationClassFromMime(String mimeString, @@ -203,7 +207,13 @@ public class DataFlavor implements java.io.Externalizable, Cloneable } catch(Exception e) { - throw new IllegalArgumentException("classname: " + e.getMessage()); + IllegalArgumentException iae; + iae = new IllegalArgumentException("mimeString: " + + mimeString + + " classLoader: " + + classLoader); + iae.initCause(e); + throw iae; } } else diff --git a/libjava/classpath/java/awt/dnd/DragSource.java b/libjava/classpath/java/awt/dnd/DragSource.java index 13ffc961510..05eb6709d47 100644 --- a/libjava/classpath/java/awt/dnd/DragSource.java +++ b/libjava/classpath/java/awt/dnd/DragSource.java @@ -90,7 +90,7 @@ public class DragSource implements Serializable */ public static DragSource getDefaultDragSource() { - return null; + return new DragSource(); } public static boolean isDragImageSupported() @@ -172,13 +172,34 @@ public class DragSource implements Serializable return flavorMap; } + /** + * Dummy DragGestureRecognizer when Toolkit doesn't support drag and drop. + */ + static class NoDragGestureRecognizer extends DragGestureRecognizer + { + NoDragGestureRecognizer(DragSource ds, Component c, int actions, + DragGestureListener dgl) + { + super(ds, c, actions, dgl); + } + + protected void registerListeners() { } + protected void unregisterListeners() { } + } + public DragGestureRecognizer createDragGestureRecognizer(Class recognizer, Component c, int actions, DragGestureListener dgl) { - return Toolkit.getDefaultToolkit () + DragGestureRecognizer dgr; + dgr = Toolkit.getDefaultToolkit () .createDragGestureRecognizer (recognizer, this, c, actions, dgl); + + if (dgr == null) + dgr = new NoDragGestureRecognizer(this, c, actions, dgl); + + return dgr; } public DragGestureRecognizer diff --git a/libjava/classpath/java/awt/doc-files/capjoin.png b/libjava/classpath/java/awt/doc-files/capjoin.png Binary files differnew file mode 100644 index 00000000000..555dca90132 --- /dev/null +++ b/libjava/classpath/java/awt/doc-files/capjoin.png diff --git a/libjava/classpath/java/awt/event/AWTEventListenerProxy.java b/libjava/classpath/java/awt/event/AWTEventListenerProxy.java index 3d9958b1abd..55a4bfe376a 100644 --- a/libjava/classpath/java/awt/event/AWTEventListenerProxy.java +++ b/libjava/classpath/java/awt/event/AWTEventListenerProxy.java @@ -72,75 +72,15 @@ public class AWTEventListenerProxy extends EventListenerProxy } /** - * Forwards events on to the delegate if they meet the event mask. + * Forwards events on to the delegate. + * + * @param event the to forward to the delagate listener * - * @param event the property change event to filter * @throws NullPointerException if the delegate this was created with is null */ public void eventDispatched(AWTEvent event) { - int id = event == null ? 0 : event.getID(); - if (((mask & AWTEvent.ACTION_EVENT_MASK) != 0 - && event instanceof ActionEvent) - || ((mask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 - && event instanceof AdjustmentEvent) - || ((mask & AWTEvent.COMPONENT_EVENT_MASK) != 0 - && event instanceof ComponentEvent - && (id >= ComponentEvent.COMPONENT_FIRST - && id <= ComponentEvent.COMPONENT_LAST)) - || ((mask & AWTEvent.CONTAINER_EVENT_MASK) != 0 - && event instanceof ContainerEvent) - || ((mask & AWTEvent.FOCUS_EVENT_MASK) != 0 - && event instanceof FocusEvent) - || ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 - && event instanceof HierarchyEvent - && (id == HierarchyEvent.ANCESTOR_MOVED - || id == HierarchyEvent.ANCESTOR_RESIZED)) - || ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 - && event instanceof HierarchyEvent - && id == HierarchyEvent.HIERARCHY_CHANGED) - || ((mask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 - && event instanceof InputMethodEvent) - || ((mask & AWTEvent.INVOCATION_EVENT_MASK) != 0 - && event instanceof InvocationEvent) - || ((mask & AWTEvent.ITEM_EVENT_MASK) != 0 - && event instanceof ItemEvent) - || ((mask & AWTEvent.KEY_EVENT_MASK) != 0 - && event instanceof KeyEvent) - || ((mask & AWTEvent.MOUSE_EVENT_MASK) != 0 - && event instanceof MouseEvent - && (id == MouseEvent.MOUSE_PRESSED - || id == MouseEvent.MOUSE_RELEASED - || id == MouseEvent.MOUSE_CLICKED - || id == MouseEvent.MOUSE_ENTERED - || id == MouseEvent.MOUSE_EXITED)) - || ((mask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 - && event instanceof MouseEvent - && (id == MouseEvent.MOUSE_MOVED - || id == MouseEvent.MOUSE_DRAGGED)) - || ((mask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 - && event instanceof MouseWheelEvent) - || ((mask & AWTEvent.PAINT_EVENT_MASK) != 0 - && event instanceof PaintEvent) - || ((mask & AWTEvent.TEXT_EVENT_MASK) != 0 - && event instanceof TextEvent) - || ((mask & AWTEvent.WINDOW_EVENT_MASK) != 0 - && event instanceof WindowEvent - && (id == WindowEvent.WINDOW_OPENED - || id == WindowEvent.WINDOW_CLOSING - || id == WindowEvent.WINDOW_CLOSED - || id == WindowEvent.WINDOW_ICONIFIED - || id == WindowEvent.WINDOW_DEICONIFIED - || id == WindowEvent.WINDOW_ACTIVATED - || id == WindowEvent.WINDOW_DEACTIVATED)) - || ((mask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 - && event instanceof WindowEvent - && (id == WindowEvent.WINDOW_GAINED_FOCUS - || id == WindowEvent.WINDOW_LOST_FOCUS)) - || ((mask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 - && event instanceof WindowEvent - && id == WindowEvent.WINDOW_STATE_CHANGED)) - ((AWTEventListener) getListener()).eventDispatched(event); + ((AWTEventListener) getListener()).eventDispatched(event); } /** diff --git a/libjava/classpath/java/awt/peer/ComponentPeer.java b/libjava/classpath/java/awt/peer/ComponentPeer.java index 1ba16923224..97b96f49cdb 100644 --- a/libjava/classpath/java/awt/peer/ComponentPeer.java +++ b/libjava/classpath/java/awt/peer/ComponentPeer.java @@ -59,76 +59,344 @@ import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; +/** + * Defines the methods that a component peer is required to implement. + */ public interface ComponentPeer { + /** + * Returns the construction status of the specified image. This is called + * by {@link Component#checkImage(Image, int, int, ImageObserver)}. + * + * @param img the image + * @param width the width of the image + * @param height the height of the image + * @param ob the image observer to be notified of updates of the status + * + * @return a bitwise ORed set of ImageObserver flags + */ int checkImage(Image img, int width, int height, - ImageObserver ob); + ImageObserver ob); + + /** + * Creates an image by starting the specified image producer. This is called + * by {@link Component#createImage(ImageProducer)}. + * + * @param prod the image producer to be used to create the image + * + * @return the created image + */ Image createImage(ImageProducer prod); + + /** + * Creates an empty image with the specified <code>width</code> and + * <code>height</code>. + * + * @param width the width of the image to be created + * @param height the height of the image to be created + * + * @return the created image + */ Image createImage(int width, int height); + + /** + * Disables the component. This is called by {@link Component#disable()}. + */ void disable(); + + /** + * Disposes the component peer. This should release all resources held by the + * peer. This is called when the component is no longer in use. + */ void dispose(); + + /** + * Enables the component. This is called by {@link Component#enable()}. + */ void enable(); + + /** + * Returns the color model of the component. This is currently not used. + * + * @return the color model of the component + */ ColorModel getColorModel(); + + /** + * Returns the font metrics for the specified font. This is called by + * {@link Component#getFontMetrics(Font)}. + * + * @param f the font for which to query the font metrics + * + * @return the font metrics for the specified font + */ FontMetrics getFontMetrics(Font f); + + /** + * Returns a {@link Graphics} object suitable for drawing on this component. + * This is called by {@link Component#getGraphics()}. + * + * @return a graphics object suitable for drawing on this component + */ Graphics getGraphics(); + + /** + * Returns the location of this component in screen coordinates. This is + * called by {@link Component#getLocationOnScreen()}. + * + * @return the location of this component in screen coordinates + */ Point getLocationOnScreen(); + + /** + * Returns the minimum size for the component. This is called by + * {@link Component#getMinimumSize()}. + * + * @return the minimum size for the component + */ Dimension getMinimumSize(); + + /** + * Returns the preferred size for the component. This is called by + * {@link Component#getPreferredSize()}. + * + * @return the preferred size for the component + */ Dimension getPreferredSize(); + + /** + * Returns the toolkit that created this peer. + * + * @return the toolkit that created this peer + */ Toolkit getToolkit(); + + /** + * Handles the given event. This is called from + * {@link Component#dispatchEvent(AWTEvent)} to give the peer a chance to + * react to events for the component. + * + * @param e the event + */ void handleEvent(AWTEvent e); + + /** + * Makes the component invisible. This is called from + * {@link Component#hide()}. + */ void hide(); /** - * Part of the earlier 1.1 API, replaced by isFocusable(). + * Returns <code>true</code> if the component can receive keyboard input + * focus. This is called from {@link Component#isFocusTraversable()}. + * + * @specnote Part of the earlier 1.1 API, replaced by isFocusable(). */ boolean isFocusTraversable(); + + /** + * Returns <code>true</code> if the component can receive keyboard input + * focus. This is called from {@link Component#isFocusable()}. + */ boolean isFocusable(); + + /** + * Returns the minimum size for the component. This is called by + * {@link Component#minimumSize()}. + * + * @return the minimum size for the component + */ Dimension minimumSize(); + + /** + * Returns the preferred size for the component. This is called by + * {@link Component#getPreferredSize()}. + * + * @return the preferred size for the component + */ Dimension preferredSize(); + void paint(Graphics graphics); + + /** + * Prepares an image for rendering on this component. This is called by + * {@link Component#prepareImage(Image, int, int, ImageObserver)}. + * + * @param img the image to prepare + * @param width the desired width of the rendered image + * @param height the desired height of the rendered image + * @param ob the image observer to be notified of updates in the preparation + * process + * + * @return <code>true</code> if the image has been fully prepared, + * <code>false</code> otherwise (in which case the image observer + * receives updates) + */ boolean prepareImage(Image img, int width, int height, ImageObserver ob); + void print(Graphics graphics); + + /** + * Repaints the specified rectangle of this component. This is called from + * {@link Component#repaint(long, int, int, int, int)}. + * + * @param tm number of milliseconds to wait with repainting + * @param x the X coordinate of the upper left corner of the damaged rectangle + * @param y the Y coordinate of the upper left corner of the damaged rectangle + * @param width the width of the damaged rectangle + * @param height the height of the damaged rectangle + */ void repaint(long tm, int x, int y, int width, int height); /** - * Part of the earlier 1.1 API, apparently replaced by argument - * form of the same method. + * Requests that this component receives the focus. This is called from + * {@link Component#requestFocus()}. + * + * @specnote Part of the earlier 1.1 API, apparently replaced by argument + * form of the same method. */ void requestFocus(); - boolean requestFocus (Component source, boolean bool1, boolean bool2, long x); + /** + * Requests that this component receives the focus. This is called from + * {@link Component#requestFocus()}. + * + * @param source TODO + * @param bool1 TODO + * @param bool2 TODO + * @param x TODO + */ + boolean requestFocus(Component source, boolean bool1, boolean bool2, long x); + + /** + * Notifies the peer that the bounds of this component have changed. This + * is called by {@link Component#reshape(int, int, int, int)}. + * + * @param x the X coordinate of the upper left corner of the component + * @param y the Y coordinate of the upper left corner of the component + * @param width the width of the component + * @param height the height of the component + */ void reshape(int x, int y, int width, int height); + + /** + * Sets the background color of the component. This is called by + * {@link Component#setBackground(Color)}. + * + * @param color the background color to set + */ void setBackground(Color color); + + /** + * Notifies the peer that the bounds of this component have changed. This + * is called by {@link Component#setBounds(int, int, int, int)}. + * + * @param x the X coordinate of the upper left corner of the component + * @param y the Y coordinate of the upper left corner of the component + * @param width the width of the component + * @param height the height of the component + */ void setBounds(int x, int y, int width, int height); /** - * Part of the earlier 1.1 API, apparently no longer needed. + * Sets the cursor of the component. This is called by + * {@link Component#setCursor(Cursor)}. + * + * @specnote Part of the earlier 1.1 API, apparently no longer needed. */ void setCursor(Cursor cursor); + /** + * Sets the enabled/disabled state of this component. This is called by + * {@link Component#setEnabled(boolean)}. + * + * @param enabled <code>true</code> to enable the component, + * <code>false</code> to disable it + */ void setEnabled(boolean enabled); + + /** + * Sets the font of the component. This is called by + * {@link Component#setFont(Font)}. + * + * @param font the font to set + */ void setFont(Font font); + + /** + * Sets the foreground color of the component. This is called by + * {@link Component#setForeground(Color)}. + * + * @param color the foreground color to set + */ void setForeground(Color color); + + /** + * Sets the visibility state of the component. This is called by + * {@link Component#setVisible(boolean)}. + * + * @param visible <code>true</code> to make the component visible, + * <code>false</code> to make it invisible + */ void setVisible(boolean visible); + + /** + * Makes the component visible. This is called by {@link Component#show()}. + */ void show(); /** * Get the graphics configuration of the component. The color model * of the component can be derived from the configuration. + * + * @return the graphics configuration of the component */ GraphicsConfiguration getGraphicsConfiguration(); /** * Part of an older API, no longer needed. */ - void setEventMask (long mask); + void setEventMask(long mask); - // Methods below are introduced since 1.1 + /** + * Returns <code>true</code> if this component has been obscured, + * <code>false</code> otherwise. This will only work if + * {@link #canDetermineObscurity()} also returns <code>true</code>. + * + * @return <code>true</code> if this component has been obscured, + * <code>false</code> otherwise. + */ boolean isObscured(); + + /** + * Returns <code>true</code> if this component peer can determine if the + * component has been obscured, <code>false</code> otherwise. + * + * @return <code>true</code> if this component peer can determine if the + * component has been obscured, <code>false</code> otherwise + */ boolean canDetermineObscurity(); + + /** + * Coalesces the specified paint event. + * + * @param e the paint event + */ void coalescePaintEvent(PaintEvent e); + + /** + * Updates the cursor. + */ void updateCursorImmediately(); + + /** + * Returns true, if this component can handle wheel scrolling, + * <code>false</code> otherwise. + * + * @return true, if this component can handle wheel scrolling, + * <code>false</code> otherwise + */ boolean handlesWheelScrolling(); /** diff --git a/libjava/classpath/java/awt/print/NoPrinterJob.java b/libjava/classpath/java/awt/print/NoPrinterJob.java new file mode 100644 index 00000000000..e9659a147e7 --- /dev/null +++ b/libjava/classpath/java/awt/print/NoPrinterJob.java @@ -0,0 +1,124 @@ +/* NoPrinterJob.java -- Fake PrinterJob that just signals no print service. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt.print; + +/** + * Fake PrinterJob that just signals no print service. This is only + * here so applications can call + * <code>PrintJob.getPrinterJob().getPrinterJob()</code> and check + * that it returns <code>null</code> which indicates no actual + * printing support is available. + */ +class NoPrinterJob extends PrinterJob +{ + public int getCopies() + { + return 0; + } + + public void setCopies(int copies) + { + // Do nothing. + } + + public String getJobName() + { + return "NoPrinterJob"; + } + + public void setJobName(String job_name) + { + // Do nothing. + } + + public String getUserName() + { + return "NoUser"; + } + + public void cancel() + { + // Do nothing. + } + + public boolean isCancelled() + { + return true; + } + + public PageFormat defaultPage(PageFormat page_format) + { + return page_format; + } + + public PageFormat pageDialog(PageFormat page_format) + { + return page_format; + } + + public void print() throws PrinterException + { + throw new PrinterException("No printer"); + } + + public boolean printDialog() + { + return false; + } + + public void setPageable(Pageable pageable) + { + // Do nothing. + } + + public void setPrintable(Printable printable) + { + // Do nothing. + } + + public void setPrintable(Printable printable, PageFormat page_format) + { + // Do nothing. + } + + public PageFormat validatePage(PageFormat page_format) + { + return page_format; + } +} diff --git a/libjava/classpath/java/awt/print/PageFormat.java b/libjava/classpath/java/awt/print/PageFormat.java index 6399552de44..0a8aa3ed0eb 100644 --- a/libjava/classpath/java/awt/print/PageFormat.java +++ b/libjava/classpath/java/awt/print/PageFormat.java @@ -1,5 +1,5 @@ /* PageFormat.java -- Information about the page format - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,254 +39,195 @@ exception statement from your version. */ package java.awt.print; /** - * This class contains information about the desired page format to - * use for printing a particular set of pages. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class PageFormat implements Cloneable -{ - -/* - * Static Variables - */ - -/** - * A constant for a landscaped page orientation. Used by - * <code>getOrientation</code> and <code>setOrientation</code>. - */ -public static final int LANDSCAPE = 0; - -/** - * A constant for a portrait page orientation. Used by - * <code>getOrientation</code> and <code>setOrientation</code>. - */ -public static final int PORTRAIT = 1; - -/** - * A constant for a reversed landscaped page orientation. This is - * the orientation used by Macintosh's for landscape. The origin is - * in the upper right hand corner instead of the upper left. The - * X and Y axes are reversed. Used by <code>getOrientation</code> and - * <code>setOrientation</code>. - */ -public static final int REVERSE_LANDSCAPE = 2; - -/*************************************************************************/ - -/* - * Instance Variables + * This class contains information about the desired page format to use for + * printing a particular set of pages. + * + * @author Aaron M. Renn (arenn@urbanophile.com) */ - -// The page orientation -private int orientation; - -// The paper type -private Paper paper; - -/*************************************************************************/ - -/* - * Constructors - */ - -/** - * This method creates a default page layout, which will be in portrait - * format. - */ -public -PageFormat() -{ - this.paper = new Paper(); - this.orientation = PORTRAIT; -} - -/*************************************************************************/ - -/* - * Instance Methods - */ - -/** - * This method returns the width of the page, in 1/72nd's of an inch. The - * "width" measured depends on orientation. - * - * @return The width of the page. - */ -public double -getWidth() -{ - return(paper.getWidth()); -} - -/*************************************************************************/ - -/** - * This method returns the height of the page, in 1/72nd's of an inch. - * The "height" measured depends on the orientation. - * - * @return The height of the page. - */ -public double -getHeight() -{ - return(paper.getHeight()); -} - -/*************************************************************************/ - -/** - * This method returns the X coordinate value of the upper leftmost - * drawable area of the paper. - * - * @return The upper leftmost imageable X coordinate. - */ -public double -getImageableX() -{ - return(paper.getImageableX()); -} - -/*************************************************************************/ - -/** - * This method returns the Y coordinate value of the upper leftmost - * drawable area of the paper. - * - * @return The upper leftmost imageable Y coordinate. - */ -public double -getImageableY() -{ - return(paper.getImageableY()); -} - -/*************************************************************************/ - -/** - * This method returns the imageable width of the paper, in 1/72nd's of - * an inch. - * - * @return The imageable width of the paper. - */ -public double -getImageableWidth() +public class PageFormat + implements Cloneable { - return(paper.getImageableWidth()); -} - -/*************************************************************************/ + /** + * A constant for a landscaped page orientation. Used by + * <code>getOrientation</code> and <code>setOrientation</code>. + */ + public static final int LANDSCAPE = 0; + + /** + * A constant for a portrait page orientation. Used by + * <code>getOrientation</code> and <code>setOrientation</code>. + */ + public static final int PORTRAIT = 1; + + /** + * A constant for a reversed landscaped page orientation. This is the + * orientation used by Macintosh's for landscape. The origin is in the + * upper right hand corner instead of the upper left. The X and Y axes + * are reversed. Used by <code>getOrientation</code> and + * <code>setOrientation</code>. + */ + public static final int REVERSE_LANDSCAPE = 2; + + // The page orientation + private int orientation; + + // The paper type + private Paper paper; + + /** + * This method creates a default page layout, which will be in portrait + * format. + */ + public PageFormat() + { + this.paper = new Paper(); + this.orientation = PORTRAIT; + } + + /** + * This method returns the width of the page, in 1/72nd's of an inch. The + * "width" measured depends on orientation. + * + * @return The width of the page. + */ + public double getWidth() + { + return paper.getWidth(); + } + + /** + * This method returns the height of the page, in 1/72nd's of an inch. The + * "height" measured depends on the orientation. + * + * @return The height of the page. + */ + public double getHeight() + { + return paper.getHeight(); + } + + /** + * This method returns the X coordinate value of the upper leftmost drawable + * area of the paper. + * + * @return The upper leftmost imageable X coordinate. + */ + public double getImageableX() + { + return paper.getImageableX(); + } + + /** + * This method returns the Y coordinate value of the upper leftmost drawable + * area of the paper. + * + * @return The upper leftmost imageable Y coordinate. + */ + public double getImageableY() + { + return paper.getImageableY(); + } + + /** + * This method returns the imageable width of the paper, in 1/72nd's of an + * inch. + * + * @return The imageable width of the paper. + */ + public double getImageableWidth() + { + return paper.getImageableWidth(); + } + + /** + * This method returns the imageable height of the paper, in 1/72nd's of an + * inch. + * + * @return The imageable height of the paper. + */ + public double getImageableHeight() + { + return paper.getImageableHeight(); + } + + /** + * Returns a copy of the <code>paper</code> object being used for this page + * format. + * + * @return A copy of the <code>Paper</code> object for this format. + */ + public Paper getPaper() + { + return (Paper) paper.clone(); + } + + /** + * Sets the <code>Paper</code> object to be used by this page format. + * + * @param paper The new <code>Paper</code> object for this page format. + */ + public void setPaper(Paper paper) + { + this.paper = paper; + } + + /** + * This method returns the current page orientation. The value returned will + * be one of the page orientation constants from this class. + * + * @return The current page orientation. + */ + public int getOrientation() + { + return orientation; + } + + /** + * This method sets the page orientation for this format to the specified + * value. It must be one of the page orientation constants from this class + * or an exception will be thrown. + * + * @param orientation The new page orientation. + * @exception IllegalArgumentException If the specified page orientation + * value is not one of the constants from this class. + */ + public void setOrientation(int orientation) throws IllegalArgumentException + { + if ((orientation != PORTRAIT) && (orientation != LANDSCAPE) + && (orientation != REVERSE_LANDSCAPE)) + throw new IllegalArgumentException("Bad page orientation value: " + + orientation); + + this.orientation = orientation; + } + + /** + * This method returns a matrix used for transforming user space coordinates + * to page coordinates. The value returned will be six doubles as described + * in <code>java.awt.geom.AffineTransform</code>. + * + * @return The transformation matrix for this page format. + */ + public double[] getMatrix() + { + throw new RuntimeException("Not implemented since I don't know what to do"); + } + + /** + * This method returns a copy of this object. + * + * @return A copy of this object. + */ + public Object clone() + { + try + { + return (super.clone()); + } + catch (CloneNotSupportedException e) + { + return (null); + } + } -/** - * This method returns the imageable height of the paper, in 1/72nd's of - * an inch. - * - * @return The imageable height of the paper. - */ -public double getImageableHeight() -{ - return(paper.getImageableHeight()); } - -/*************************************************************************/ - -/** - * Returns a copy of the <code>paper</code> object being used for this - * page format. - * - * @return A copy of the <code>Paper</code> object for this format. - */ -public Paper -getPaper() -{ - return((Paper)paper.clone()); -} - -/*************************************************************************/ - -/** - * Sets the <code>Paper</code> object to be used by this page format. - * - * @param paper The new <code>Paper</code> object for this page format. - */ -public void -setPaper(Paper paper) -{ - this.paper = paper; -} - -/*************************************************************************/ - -/** - * This method returns the current page orientation. The value returned - * will be one of the page orientation constants from this class. - * - * @return The current page orientation. - */ -public int -getOrientation() -{ - return(orientation); -} - -/*************************************************************************/ - -/** - * This method sets the page orientation for this format to the - * specified value. It must be one of the page orientation constants - * from this class or an exception will be thrown. - * - * @param orientation The new page orientation. - * - * @exception IllegalArgumentException If the specified page orientation - * value is not one of the constants from this class. - */ -public void -setOrientation(int orientation) throws IllegalArgumentException -{ - if ((orientation != PORTRAIT) && - (orientation != LANDSCAPE) && - (orientation != REVERSE_LANDSCAPE)) - throw new IllegalArgumentException("Bad page orientation value: " + - orientation); - - this.orientation = orientation; -} - -/*************************************************************************/ - -/** - * This method returns a matrix used for transforming user space - * coordinates to page coordinates. The value returned will be six - * doubles as described in <code>java.awt.geom.AffineTransform</code>. - * - * @return The transformation matrix for this page format. - */ -public double[] -getMatrix() -{ - throw new RuntimeException("Not implemented since I don't know what to do"); -} - -/*************************************************************************/ - -/** - * This method returns a copy of this object. - * - * @return A copy of this object. - */ -public Object -clone() -{ - try - { - return(super.clone()); - } - catch(CloneNotSupportedException e) - { - return(null); - } -} - -} // class PageFormat - diff --git a/libjava/classpath/java/awt/print/Pageable.java b/libjava/classpath/java/awt/print/Pageable.java index 12fa542a8c6..d61195a92f0 100644 --- a/libjava/classpath/java/awt/print/Pageable.java +++ b/libjava/classpath/java/awt/print/Pageable.java @@ -1,5 +1,5 @@ /* Pageable.java -- Pages to be printed - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,75 +39,52 @@ exception statement from your version. */ package java.awt.print; /** - * This interface represents pages that are to be printed. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface represents pages that are to be printed. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ public interface Pageable { - -/* - * Static Variables - */ - -/** - * This constant is returned when <code>getNumberOfPages()</code> - * cannot determine the number of pages available for printing. - */ -int UNKNOWN_NUMBER_OF_PAGES = -1; - -/*************************************************************************/ - -/* - * Instance Methods - */ - -/** - * This method returns the number of pages this object contains, or - * <code>UNKNOWN_NUMBER_OF_PAGES</code> if it cannot determine the number - * of pages to be printed. - * - * @return The number of pages to be printed, or - * <code>UNKNOWN_NUMBER_OF_PAGES</code> if this is unknown. - */ -int -getNumberOfPages(); - -/*************************************************************************/ - -/** - * This method returns the <code>PageFormat</code> instance for the - * specified page. Page numbers start at zero. An exception is thrown if - * the requested page does not exist. - * - * @param pageIndex The index of the page to return the - * <code>PageFormat</code> for. - * - * @return The <code>PageFormat</code> for the requested page. - * - * @exception IndexOutOfBoundsException If the requested page number does - * not exist. - */ -PageFormat -getPageFormat(int pageIndex) throws IndexOutOfBoundsException; - -/*************************************************************************/ - -/** - * This method returns the <code>Printable</code> instance for the - * specified page. Page numbers start at zero. An exception is thrown if - * the requested page does not exist. - * - * @param pageIndex The index of the page to return the - * <code>Printable</code> for. - * - * @return The <code>Printable</code> for the requested page. - * - * @exception IndexOutOfBoundsException If the requested page number does - * not exist. - */ -Printable -getPrintable(int pageIndex) throws IndexOutOfBoundsException; - -} // interface Pageable - + /** + * This constant is returned when <code>getNumberOfPages()</code> cannot + * determine the number of pages available for printing. + */ + int UNKNOWN_NUMBER_OF_PAGES = - 1; + + /** + * This method returns the number of pages this object contains, or + * <code>UNKNOWN_NUMBER_OF_PAGES</code> if it cannot determine the number + * of pages to be printed. + * + * @return The number of pages to be printed, or + * <code>UNKNOWN_NUMBER_OF_PAGES</code> if this is unknown. + */ + int getNumberOfPages(); + + /** + * This method returns the <code>PageFormat</code> instance for the + * specified page. Page numbers start at zero. An exception is thrown if the + * requested page does not exist. + * + * @param pageIndex The index of the page to return the + * <code>PageFormat</code> for. + * @return The <code>PageFormat</code> for the requested page. + * @exception IndexOutOfBoundsException If the requested page number does + * not exist. + */ + PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException; + + /** + * This method returns the <code>Printable</code> instance for the specified + * page. Page numbers start at zero. An exception is thrown if the requested + * page does not exist. + * + * @param pageIndex The index of the page to return the + * <code>Printable</code> for. + * @return The <code>Printable</code> for the requested page. + * @exception IndexOutOfBoundsException If the requested page number does + * not exist. + */ + Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException; + +} diff --git a/libjava/classpath/java/awt/print/Paper.java b/libjava/classpath/java/awt/print/Paper.java index 4579da3ea3c..fb7ba91158f 100644 --- a/libjava/classpath/java/awt/print/Paper.java +++ b/libjava/classpath/java/awt/print/Paper.java @@ -1,5 +1,5 @@ /* Paper.java -- Information about a paper type. - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,198 +39,159 @@ exception statement from your version. */ package java.awt.print; /** - * This class describes a particular type of paper. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class Paper implements Cloneable -{ - -/* - * Instance Variables + * This class describes a particular type of paper. + * + * @author Aaron M. Renn (arenn@urbanophile.com) */ - -// Height of the paper -private double height; - -// Width of the paper -private double width; - -// Upper left imageable X coordinate -private double imageableX; - -// Upper left imageable Y coordinate -private double imageableY; - -// Imageable width of the page -private double imageableWidth; - -// Imageable height of the page -private double imageableHeight; - -/*************************************************************************/ - -/* - * Constructor - */ - -/** - * This method creates a letter sized paper with one inch margins - */ -public -Paper() -{ - width = 8.5 * 72; - height = 11 * 72; - imageableX = 72; - imageableY = 72; - imageableWidth = width - (2 * 72); - imageableHeight = height - (2 * 72); -} - -/*************************************************************************/ - -/** - * This method returns the height of the paper in 1/72nds of an inch. - * - * @return The height of the paper in 1/72nds of an inch. - */ -public double -getHeight() +public class Paper + implements Cloneable { - return(height); -} + // Height of the paper + private double height; + + // Width of the paper + private double width; + + // Upper left imageable X coordinate + private double imageableX; + + // Upper left imageable Y coordinate + private double imageableY; + + // Imageable width of the page + private double imageableWidth; + + // Imageable height of the page + private double imageableHeight; + + /** + * This method creates a letter sized paper with one inch margins + */ + public Paper() + { + width = 8.5 * 72; + height = 11 * 72; + imageableX = 72; + imageableY = 72; + imageableWidth = width - (2 * 72); + imageableHeight = height - (2 * 72); + } + + /** + * This method returns the height of the paper in 1/72nds of an inch. + * + * @return The height of the paper in 1/72nds of an inch. + */ + public double getHeight() + { + return height; + } + + /** + * Returns the width of the paper in 1/72nds of an inch. + * + * @return The width of the paper in 1/72nds of an inch. + */ + public double getWidth() + { + return width; + } + + /** + * This method returns the X coordinate of the upper left hand corner of the + * imageable area of the paper. + * + * @return The X coordinate of the upper left hand corner of the imageable + * area of the paper. + */ + public double getImageableX() + { + return imageableX; + } + + /** + * This method returns the Y coordinate of the upper left hand corner of the + * imageable area of the paper. + * + * @return The Y coordinate of the upper left hand corner of the imageable + * area of the paper. + */ + public double getImageableY() + { + return imageableY; + } + + /** + * Returns the width of the imageable area of the paper. + * + * @return The width of the imageable area of the paper. + */ + public double getImageableWidth() + { + return imageableWidth; + } + + /** + * Returns the height of the imageable area of the paper. + * + * @return The height of the imageable area of the paper. + */ + public double getImageableHeight() + { + return imageableHeight; + } + + /** + * This method sets the size of the paper to the specified width and height, + * which are specified in 1/72nds of an inch. + * + * @param width The width of the paper in 1/72nds of an inch. + * @param height The height of the paper in 1/72nds of an inch. + */ + public void setSize(double width, double height) + { + this.width = width; + this.height = height; + } + + /** + * This method sets the imageable area of the paper by specifying the + * coordinates of the upper left hand corner of that area, and its length + * and height. All values are in 1/72nds of an inch. + * + * @param imageableX The X coordinate of the upper left hand corner of the + * imageable area, in 1/72nds of an inch. + * @param imageableY The Y coordinate of the upper left hand corner of the + * imageable area, in 1/72nds of an inch. + * @param imageableWidth The width of the imageable area of the paper, in + * 1/72nds of an inch. + * @param imageableHeight The heigth of the imageable area of the paper, in + * 1/72nds of an inch. + */ + public void setImageableArea(double imageableX, double imageableY, + double imageableWidth, double imageableHeight) + { + this.imageableX = imageableX; + this.imageableY = imageableY; + this.imageableWidth = imageableWidth; + this.imageableHeight = imageableHeight; + } + + /** + * This method creates a copy of this object. + * + * @return A copy of this object. + */ + public Object clone() + { + try + { + return (super.clone()); + } + catch (CloneNotSupportedException e) + { + return (null); + } + } -/*************************************************************************/ - -/** - * Returns the width of the paper in 1/72nds of an inch. - * - * @return The width of the paper in 1/72nds of an inch. - */ -public double -getWidth() -{ - return(width); } - -/*************************************************************************/ - -/** - * This method returns the X coordinate of the upper left hand corner - * of the imageable area of the paper. - * - * @return The X coordinate of the upper left hand corner of the imageable - * area of the paper. - */ -public double -getImageableX() -{ - return(imageableX); -} - -/*************************************************************************/ - -/** - * This method returns the Y coordinate of the upper left hand corner - * of the imageable area of the paper. - * - * @return The Y coordinate of the upper left hand corner of the imageable - * area of the paper. - */ -public double -getImageableY() -{ - return(imageableY); -} - -/*************************************************************************/ - -/** - * Returns the width of the imageable area of the paper. - * - * @return The width of the imageable area of the paper. - */ -public double -getImageableWidth() -{ - return(imageableWidth); -} - -/*************************************************************************/ - -/** - * Returns the height of the imageable area of the paper. - * - * @return The height of the imageable area of the paper. - */ -public double -getImageableHeight() -{ - return(imageableHeight); -} - -/*************************************************************************/ - -/** - * This method sets the size of the paper to the specified width and - * height, which are specified in 1/72nds of an inch. - * - * @param width The width of the paper in 1/72nds of an inch. - * @param height The height of the paper in 1/72nds of an inch. - */ -public void -setSize(double width, double height) -{ - this.width = width; - this.height = height; -} - -/*************************************************************************/ - -/** - * This method sets the imageable area of the paper by specifying the - * coordinates of the upper left hand corner of that area, and its - * length and height. All values are in 1/72nds of an inch. - * - * @param imageableX The X coordinate of the upper left hand corner of - * the imageable area, in 1/72nds of an inch. - * @param imageableY The Y coordinate of the upper left hand corner of - * the imageable area, in 1/72nds of an inch. - * @param imageableWidth The width of the imageable area of the paper, - * in 1/72nds of an inch. - * @param imageableHeight The heigth of the imageable area of the paper, - * in 1/72nds of an inch. - */ -public void -setImageableArea(double imageableX, double imageableY, - double imageableWidth, double imageableHeight) -{ - this.imageableX = imageableX; - this.imageableY = imageableY; - this.imageableWidth = imageableWidth; - this.imageableHeight = imageableHeight; -} - -/*************************************************************************/ - -/** - * This method creates a copy of this object. - * - * @return A copy of this object. - */ -public Object -clone() -{ - try - { - return(super.clone()); - } - catch(CloneNotSupportedException e) - { - return(null); - } -} - -} // class Paper - diff --git a/libjava/classpath/java/awt/print/PrinterGraphics.java b/libjava/classpath/java/awt/print/PrinterGraphics.java index 5ca64190424..62fde8406dd 100644 --- a/libjava/classpath/java/awt/print/PrinterGraphics.java +++ b/libjava/classpath/java/awt/print/PrinterGraphics.java @@ -1,5 +1,5 @@ /* PrinterGraphics.java -- Hook to return print job controller. - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,23 +39,20 @@ exception statement from your version. */ package java.awt.print; /** - * This interface is implemented by the <code>Graphics</code> instance - * that is used for rendering pages. It provides a hook to return the - * object that is controlling the print job. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface is implemented by the <code>Graphics</code> instance that is + * used for rendering pages. It provides a hook to return the object that is + * controlling the print job. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ public interface PrinterGraphics { - -/** - * This method returns the instance of <code>PrinterJob</code> that is - * controlling this print job. - * - * @return The <code>PrinterJob</code> that is controlling this print job. - */ -PrinterJob -getPrinterJob(); - -} // interface PrinterGraphics - + /** + * This method returns the instance of <code>PrinterJob</code> that is + * controlling this print job. + * + * @return The <code>PrinterJob</code> that is controlling this print job. + */ + PrinterJob getPrinterJob(); + +} diff --git a/libjava/classpath/java/awt/print/PrinterJob.java b/libjava/classpath/java/awt/print/PrinterJob.java index e1aeabc3e62..7f67a6b048b 100644 --- a/libjava/classpath/java/awt/print/PrinterJob.java +++ b/libjava/classpath/java/awt/print/PrinterJob.java @@ -1,5 +1,5 @@ /* PrinterJob.java -- This job is the printer control class - Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -61,7 +61,7 @@ public abstract class PrinterJob public static PrinterJob getPrinterJob() { // FIXME: Need to fix this to load a default implementation instance. - return null; + return new NoPrinterJob(); } /** diff --git a/libjava/classpath/java/beans/DefaultPersistenceDelegate.java b/libjava/classpath/java/beans/DefaultPersistenceDelegate.java index 9dd1ae564f7..ca1041fefc9 100644 --- a/libjava/classpath/java/beans/DefaultPersistenceDelegate.java +++ b/libjava/classpath/java/beans/DefaultPersistenceDelegate.java @@ -157,6 +157,23 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { + // Calling the supertype's implementation of initialize makes it + // possible that descendants of classes like AbstractHashMap + // or Hashtable are serialized correctly. This mechanism grounds on + // two other facts: + // * Each class which has not registered a special purpose + // PersistenceDelegate is handled by a DefaultPersistenceDelegate + // instance. + // * PersistenceDelegate.initialize() is implemented in a way that it + // calls the initialize method of the superclass' persistence delegate. + super.initialize(type, oldInstance, newInstance, out); + + // Suppresses the writing of property setting statements when this delegate + // is not used for the exact instance type. By doing so the following code + // is called only once per object. + if (type != oldInstance.getClass()) + return; + try { PropertyDescriptor[] propertyDescs = Introspector.getBeanInfo( diff --git a/libjava/classpath/java/beans/Encoder.java b/libjava/classpath/java/beans/Encoder.java index 9b96aaa8ea6..b9d135831a8 100644 --- a/libjava/classpath/java/beans/Encoder.java +++ b/libjava/classpath/java/beans/Encoder.java @@ -1,5 +1,5 @@ /* Encoder.java - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,21 +38,16 @@ package java.beans; +import gnu.java.beans.DefaultExceptionListener; import gnu.java.beans.encoder.ArrayPersistenceDelegate; import gnu.java.beans.encoder.ClassPersistenceDelegate; import gnu.java.beans.encoder.CollectionPersistenceDelegate; import gnu.java.beans.encoder.MapPersistenceDelegate; import gnu.java.beans.encoder.PrimitivePersistenceDelegate; -import java.util.ArrayList; +import java.util.AbstractCollection; import java.util.HashMap; -import java.util.HashSet; import java.util.IdentityHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.Vector; /** * @author Robert Schuster (robertschuster@fsfe.org) @@ -123,31 +118,11 @@ public class Encoder delegates.put(Object[].class, new ArrayPersistenceDelegate()); pd = new CollectionPersistenceDelegate(); - delegates.put(ArrayList.class, pd); - delegates.put(LinkedList.class, pd); - delegates.put(Vector.class, pd); - delegates.put(HashSet.class, pd); - delegates.put(LinkedHashSet.class, pd); - delegates.put(TreeSet.class, pd); + delegates.put(AbstractCollection.class, pd); pd = new MapPersistenceDelegate(); - delegates.put(HashMap.class, pd); - delegates.put(TreeMap.class, pd); + delegates.put(java.util.AbstractMap.class, pd); delegates.put(java.util.Hashtable.class, pd); - delegates.put(java.util.IdentityHashMap.class, pd); - - delegates.put(java.util.LinkedHashMap.class, pd); - delegates.put(java.util.Properties.class, pd); - - delegates.put(java.awt.RenderingHints.class, pd); - delegates.put(java.util.WeakHashMap.class, pd); - delegates.put(javax.swing.UIDefaults.class, pd); - - // TODO: These classes need to be implemented first - //delegates.put(java.security.AuthProvider.class, pd); - //delegates.put(java.util.concurrent.ConcurrentHashMap.class, pd); - //delegates.put(java.util.EnumMap.class, pd); - //delegates.put(javax.management.openmbean.TabularDataSupport.class, pd); defaultPersistenceDelegate = new DefaultPersistenceDelegate(); delegates.put(Object.class, defaultPersistenceDelegate); @@ -194,14 +169,8 @@ public class Encoder */ public void setExceptionListener(ExceptionListener listener) { - exceptionListener = (listener != null) ? listener : new ExceptionListener() - { - public void exceptionThrown(Exception e) - { - System.err.println("exception thrown: " + e); - e.printStackTrace(); - } - }; + exceptionListener = (listener != null) + ? listener : DefaultExceptionListener.INSTANCE; } /** diff --git a/libjava/classpath/java/beans/PersistenceDelegate.java b/libjava/classpath/java/beans/PersistenceDelegate.java index b33cbcbed06..77953b67682 100644 --- a/libjava/classpath/java/beans/PersistenceDelegate.java +++ b/libjava/classpath/java/beans/PersistenceDelegate.java @@ -59,9 +59,8 @@ public abstract class PersistenceDelegate { type = type.getSuperclass(); - PersistenceDelegate pd = out.getPersistenceDelegate( - oldInstance.getClass().getSuperclass()); - + PersistenceDelegate pd = out.getPersistenceDelegate(type); + pd.initialize(type, oldInstance, newInstance, out); } } diff --git a/libjava/classpath/java/beans/PropertyChangeSupport.java b/libjava/classpath/java/beans/PropertyChangeSupport.java index 991390b5631..e944e151251 100644 --- a/libjava/classpath/java/beans/PropertyChangeSupport.java +++ b/libjava/classpath/java/beans/PropertyChangeSupport.java @@ -1,5 +1,6 @@ /* PropertyChangeSupport.java -- support to manage property change listeners - Copyright (C) 1998, 1999, 2000, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -120,14 +121,17 @@ public class PropertyChangeSupport implements Serializable * property change events will be sent to this listener. The listener add * is not unique: that is, <em>n</em> adds with the same listener will * result in <em>n</em> events being sent to that listener for every - * property change. Adding a null listener may cause a NullPointerException - * down the road. This method will unwrap a PropertyChangeListenerProxy, + * property change. Adding a null listener is silently ignored. + * This method will unwrap a PropertyChangeListenerProxy, * registering the underlying delegate to the named property list. * * @param l the listener to add */ public synchronized void addPropertyChangeListener(PropertyChangeListener l) { + if (l == null) + return; + if (l instanceof PropertyChangeListenerProxy) { PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l; @@ -216,8 +220,8 @@ public class PropertyChangeSupport implements Serializable * cumulative, too; if you are registered to listen to receive events on * all property changes, and then you register on a particular property, * you will receive change events for that property twice. Adding a null - * listener may cause a NullPointerException down the road. This method - * will unwrap a PropertyChangeListenerProxy, registering the underlying + * listener is silently ignored. This method will unwrap a + * PropertyChangeListenerProxy, registering the underlying * delegate to the named property list if the names match, and discarding * it otherwise. * @@ -228,6 +232,9 @@ public class PropertyChangeSupport implements Serializable public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener l) { + if (l == null) + return; + while (l instanceof PropertyChangeListenerProxy) { PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l; @@ -290,17 +297,16 @@ public class PropertyChangeSupport implements Serializable /** * Returns an array of all property change listeners registered under the - * given property name. If there are no registered listeners, this returns - * an empty array. + * given property name. If there are no registered listeners, or + * propertyName is null, this returns an empty array. * * @return the array of registered listeners - * @throws NullPointerException if propertyName is null * @since 1.4 */ public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { - if (children == null) + if (children == null || propertyName == null) return new PropertyChangeListener[0]; PropertyChangeSupport s = (PropertyChangeSupport) children.get(propertyName); @@ -455,7 +461,6 @@ public class PropertyChangeSupport implements Serializable * * @param propertyName the property that may be listened on * @return whether the property is being listened on - * @throws NullPointerException if propertyName is null */ public synchronized boolean hasListeners(String propertyName) { diff --git a/libjava/classpath/java/beans/PropertyDescriptor.java b/libjava/classpath/java/beans/PropertyDescriptor.java index a22d6252e28..da2ca78ae67 100644 --- a/libjava/classpath/java/beans/PropertyDescriptor.java +++ b/libjava/classpath/java/beans/PropertyDescriptor.java @@ -37,6 +37,8 @@ exception statement from your version. */ package java.beans; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** @@ -344,6 +346,71 @@ public class PropertyDescriptor extends FeatureDescriptor this.propertyEditorClass = propertyEditorClass; } + /** + * Instantiate a property editor using the property editor class. + * If no property editor class has been set, this will return null. + * If the editor class has a public constructor which takes a single + * argument, that will be used and the bean parameter will be passed + * to it. Otherwise, a public no-argument constructor will be used, + * if available. This method will return null if no constructor is + * found or if construction fails for any reason. + * @param bean the argument to the constructor + * @return a new PropertyEditor, or null on error + * @since 1.5 + */ + public PropertyEditor createPropertyEditor(Object bean) + { + if (propertyEditorClass == null) + return null; + Constructor c = findConstructor(propertyEditorClass, + new Class[] { Object.class }); + if (c != null) + return instantiateClass(c, new Object[] { bean }); + c = findConstructor(propertyEditorClass, null); + if (c != null) + return instantiateClass(c, null); + return null; + } + + // Helper method to look up a constructor and return null if it is not + // found. + private Constructor findConstructor(Class k, Class[] argTypes) + { + try + { + return k.getConstructor(argTypes); + } + catch (NoSuchMethodException _) + { + return null; + } + } + + // Helper method to instantiate an object but return null on error. + private PropertyEditor instantiateClass(Constructor c, Object[] args) + { + try + { + return (PropertyEditor) c.newInstance(args); + } + catch (InstantiationException _) + { + return null; + } + catch (InvocationTargetException _) + { + return null; + } + catch (IllegalAccessException _) + { + return null; + } + catch (ClassCastException _) + { + return null; + } + } + private void findMethods( Class beanClass, String getMethodName1, diff --git a/libjava/classpath/java/beans/XMLDecoder.java b/libjava/classpath/java/beans/XMLDecoder.java index 238fd6bed91..7618bb8cb0e 100644 --- a/libjava/classpath/java/beans/XMLDecoder.java +++ b/libjava/classpath/java/beans/XMLDecoder.java @@ -1,5 +1,5 @@ /* java.beans.XMLDecoder -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,7 +38,7 @@ exception statement from your version. */ package java.beans; -import gnu.java.beans.decoder.DefaultExceptionListener; +import gnu.java.beans.DefaultExceptionListener; import gnu.java.beans.decoder.PersistenceParser; import java.io.IOException; @@ -289,7 +289,7 @@ public class XMLDecoder // uses a default implementation when null if (listener == null) { - listener = new DefaultExceptionListener(); + listener = DefaultExceptionListener.INSTANCE; } exceptionListener = listener; } diff --git a/libjava/classpath/java/beans/XMLEncoder.java b/libjava/classpath/java/beans/XMLEncoder.java index f9cbe63963d..feff68bd360 100644 --- a/libjava/classpath/java/beans/XMLEncoder.java +++ b/libjava/classpath/java/beans/XMLEncoder.java @@ -168,6 +168,8 @@ public class XMLEncoder extends Encoder // an erroneous state to the ScanEngine without behaving different // to the JDK. scanEngine.revoke(); + + return; } writeObject(value); diff --git a/libjava/classpath/java/io/InputStream.java b/libjava/classpath/java/io/InputStream.java index 86d1cd74914..e56197a837e 100644 --- a/libjava/classpath/java/io/InputStream.java +++ b/libjava/classpath/java/io/InputStream.java @@ -193,10 +193,8 @@ public abstract class InputStream */ public int read(byte[] b, int off, int len) throws IOException { - if (off < 0 || len < 0 || off + len > b.length) + if (off < 0 || len < 0 || b.length - off < len) throw new IndexOutOfBoundsException(); - if (b.length == 0) - return 0; int i, ch; diff --git a/libjava/classpath/java/io/InputStreamReader.java b/libjava/classpath/java/io/InputStreamReader.java index ef8fd4542db..936a03c95e0 100644 --- a/libjava/classpath/java/io/InputStreamReader.java +++ b/libjava/classpath/java/io/InputStreamReader.java @@ -1,5 +1,6 @@ /* InputStreamReader.java -- Reader than transforms bytes to chars - Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +39,7 @@ exception statement from your version. */ package java.io; +import gnu.classpath.SystemProperties; import gnu.java.nio.charset.EncodingHelper; import java.nio.ByteBuffer; @@ -145,7 +147,7 @@ public class InputStreamReader extends Reader this.in = in; try { - encoding = System.getProperty("file.encoding"); + encoding = SystemProperties.getProperty("file.encoding"); // Don't use NIO if avoidable if(EncodingHelper.isISOLatin1(encoding)) { @@ -231,12 +233,20 @@ public class InputStreamReader extends Reader * charset to decode the bytes in the InputStream into * characters. * - * @since 1.5 + * @since 1.4 */ public InputStreamReader(InputStream in, Charset charset) { + if (in == null) + throw new NullPointerException(); this.in = in; decoder = charset.newDecoder(); + try { + maxBytesPerChar = charset.newEncoder().maxBytesPerChar(); + } catch(UnsupportedOperationException _){ + maxBytesPerChar = 1f; + } + decoder.onMalformedInput(CodingErrorAction.REPLACE); decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); decoder.reset(); @@ -247,9 +257,11 @@ public class InputStreamReader extends Reader * Creates an InputStreamReader that uses the given charset decoder * to decode the bytes in the InputStream into characters. * - * @since 1.5 + * @since 1.4 */ public InputStreamReader(InputStream in, CharsetDecoder decoder) { + if (in == null) + throw new NullPointerException(); this.in = in; this.decoder = decoder; diff --git a/libjava/classpath/java/io/ObjectInputStream.java b/libjava/classpath/java/io/ObjectInputStream.java index 750c6989f25..91832f94e2c 100644 --- a/libjava/classpath/java/io/ObjectInputStream.java +++ b/libjava/classpath/java/io/ObjectInputStream.java @@ -1,5 +1,5 @@ /* ObjectInputStream.java -- Class used to read serialized objects - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -555,8 +555,7 @@ public class ObjectInputStream extends InputStream classLookupTable.put(clazz, osc); setBlockDataMode(oldmode); - // find the first non-serializable, non-abstract - // class in clazz's inheritance hierarchy + // find the first non-serializable class in clazz's inheritance hierarchy Class first_nonserial = clazz.getSuperclass(); // Maybe it is a primitive class, those don't have a super class, // or Object itself. Otherwise we can keep getting the superclass @@ -565,9 +564,8 @@ public class ObjectInputStream extends InputStream if (first_nonserial == null) first_nonserial = clazz; else - while (Serializable.class.isAssignableFrom(first_nonserial) - || Modifier.isAbstract(first_nonserial.getModifiers())) - first_nonserial = first_nonserial.getSuperclass(); + while (Serializable.class.isAssignableFrom(first_nonserial)) + first_nonserial = first_nonserial.getSuperclass(); final Class local_constructor_class = first_nonserial; @@ -1596,7 +1594,14 @@ public class ObjectInputStream extends InputStream private void readNextBlock() throws IOException { - readNextBlock(this.realInputStream.readByte()); + byte marker = this.realInputStream.readByte(); + while (marker == TC_RESET) + { + if(dump) dumpElementln("RESET"); + clearHandles(); + marker = this.realInputStream.readByte(); + } + readNextBlock(marker); } private void readNextBlock(byte marker) throws IOException diff --git a/libjava/classpath/java/io/ObjectOutputStream.java b/libjava/classpath/java/io/ObjectOutputStream.java index 961d5e3099f..55a12e4eae8 100644 --- a/libjava/classpath/java/io/ObjectOutputStream.java +++ b/libjava/classpath/java/io/ObjectOutputStream.java @@ -1,5 +1,5 @@ /* ObjectOutputStream.java -- Class used to write serialized objects - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -421,6 +421,8 @@ public class ObjectOutputStream extends OutputStream for (int i = 0; i < intfs.length; i++) realOutput.writeUTF(intfs[i].getName()); + assignNewHandle(osc); + boolean oldmode = setBlockDataMode(true); annotateProxyClass(osc.forClass()); setBlockDataMode(oldmode); diff --git a/libjava/classpath/java/lang/Character.java b/libjava/classpath/java/lang/Character.java index 3c88ff805c7..98ad147aaa3 100644 --- a/libjava/classpath/java/lang/Character.java +++ b/libjava/classpath/java/lang/Character.java @@ -41,6 +41,8 @@ package java.lang; import gnu.java.lang.CharData; import java.io.Serializable; +import java.text.Collator; +import java.util.Locale; /** * Wrapper class for the primitive char data type. In addition, this class @@ -133,10 +135,10 @@ public final class Character implements Serializable, Comparable * is in at most one of these blocks. * * This inner class was generated automatically from - * <code>doc/unicode/Block-3.txt</code>, by some perl scripts. + * <code>doc/unicode/Blocks-4.0.0.txt</code>, by some perl scripts. * This Unicode definition file can be found on the * <a href="http://www.unicode.org">http://www.unicode.org</a> website. - * JDK 1.4 uses Unicode version 3.0.0. + * JDK 1.5 uses Unicode version 4.0.0. * * @author scripts/unicode-blocks.pl (written by Eric Blake) * @since 1.2 @@ -144,10 +146,18 @@ public final class Character implements Serializable, Comparable public static final class UnicodeBlock extends Subset { /** The start of the subset. */ - private final char start; + private final int start; /** The end of the subset. */ - private final char end; + private final int end; + + /** The canonical name of the block according to the Unicode standard. */ + private final String canonicalName; + + /** Constants for the <code>forName()</code> method */ + private static final int CANONICAL_NAME = 0; + private static final int NO_SPACES_NAME = 1; + private static final int CONSTANT_NAME = 2; /** * Constructor for strictly defined blocks. @@ -155,25 +165,46 @@ public final class Character implements Serializable, Comparable * @param start the start character of the range * @param end the end character of the range * @param name the block name + * @param canonicalName the name of the block as defined in the Unicode + * standard. */ - private UnicodeBlock(char start, char end, String name) + private UnicodeBlock(int start, int end, String name, + String canonicalName) { super(name); this.start = start; this.end = end; + this.canonicalName = canonicalName; } /** * Returns the Unicode character block which a character belongs to. + * <strong>Note</strong>: This method does not support the use of + * supplementary characters. For such support, <code>of(int)</code> + * should be used instead. * * @param ch the character to look up * @return the set it belongs to, or null if it is not in one */ public static UnicodeBlock of(char ch) { - // Special case, since SPECIALS contains two ranges. - if (ch == '\uFEFF') - return SPECIALS; + return of((int) ch); + } + + /** + * Returns the Unicode character block which a code point belongs to. + * + * @param codePoint the character to look up + * @return the set it belongs to, or null if it is not in one. + * @throws IllegalArgumentException if the specified code point is + * invalid. + * @since 1.5 + */ + public static UnicodeBlock of(int codePoint) + { + if (codePoint > MAX_CODE_POINT) + throw new IllegalArgumentException("The supplied integer value is " + + "too large to be a codepoint."); // Simple binary search for the correct block. int low = 0; int hi = sets.length - 1; @@ -181,9 +212,9 @@ public final class Character implements Serializable, Comparable { int mid = (low + hi) >> 1; UnicodeBlock b = sets[mid]; - if (ch < b.start) + if (codePoint < b.start) hi = mid - 1; - else if (ch > b.end) + else if (codePoint > b.end) low = mid + 1; else return b; @@ -192,703 +223,1300 @@ public final class Character implements Serializable, Comparable } /** + * <p> + * Returns the <code>UnicodeBlock</code> with the given name, as defined + * by the Unicode standard. The version of Unicode in use is defined by + * the <code>Character</code> class, and the names are given in the + * <code>Blocks-<version>.txt</code> file corresponding to that version. + * The name may be specified in one of three ways: + * </p> + * <ol> + * <li>The canonical, human-readable name used by the Unicode standard. + * This is the name with all spaces and hyphens retained. For example, + * `Basic Latin' retrieves the block, UnicodeBlock.BASIC_LATIN.</li> + * <li>The canonical name with all spaces removed e.g. `BasicLatin'.</li> + * <li>The name used for the constants specified by this class, which + * is the canonical name with all spaces and hyphens replaced with + * underscores e.g. `BASIC_LATIN'</li> + * </ol> + * <p> + * The names are compared case-insensitively using the case comparison + * associated with the U.S. English locale. The method recognises the + * previous names used for blocks as well as the current ones. At + * present, this simply means that the deprecated `SURROGATES_AREA' + * will be recognised by this method (the <code>of()</code> methods + * only return one of the three new surrogate blocks). + * </p> + * + * @param blockName the name of the block to look up. + * @return the specified block. + * @throws NullPointerException if the <code>blockName</code> is + * <code>null</code>. + * @throws IllegalArgumentException if the name does not match any Unicode + * block. + * @since 1.5 + */ + public static final UnicodeBlock forName(String blockName) + { + int type; + if (blockName.indexOf(' ') != -1) + type = CANONICAL_NAME; + else if (blockName.indexOf('_') != -1) + type = CONSTANT_NAME; + else + type = NO_SPACES_NAME; + Collator usCollator = Collator.getInstance(Locale.US); + usCollator.setStrength(Collator.PRIMARY); + /* Special case for deprecated blocks not in sets */ + switch (type) + { + case CANONICAL_NAME: + if (usCollator.compare(blockName, "Surrogates Area") == 0) + return SURROGATES_AREA; + break; + case NO_SPACES_NAME: + if (usCollator.compare(blockName, "SurrogatesArea") == 0) + return SURROGATES_AREA; + break; + case CONSTANT_NAME: + if (usCollator.compare(blockName, "SURROGATES_AREA") == 0) + return SURROGATES_AREA; + break; + } + /* Other cases */ + int setLength = sets.length; + switch (type) + { + case CANONICAL_NAME: + for (int i = 0; i < setLength; i++) + { + UnicodeBlock block = sets[i]; + if (usCollator.compare(blockName, block.canonicalName) == 0) + return block; + } + break; + case NO_SPACES_NAME: + for (int i = 0; i < setLength; i++) + { + UnicodeBlock block = sets[i]; + String nsName = block.canonicalName.replaceAll(" ",""); + if (usCollator.compare(blockName, nsName) == 0) + return block; + } + break; + case CONSTANT_NAME: + for (int i = 0; i < setLength; i++) + { + UnicodeBlock block = sets[i]; + if (usCollator.compare(blockName, block.toString()) == 0) + return block; + } + break; + } + throw new IllegalArgumentException("No Unicode block found for " + + blockName + "."); + } + + /** * Basic Latin. - * '\u0000' - '\u007F'. + * 0x0000 - 0x007F. */ public static final UnicodeBlock BASIC_LATIN - = new UnicodeBlock('\u0000', '\u007F', - "BASIC_LATIN"); + = new UnicodeBlock(0x0000, 0x007F, + "BASIC_LATIN", + "Basic Latin"); /** * Latin-1 Supplement. - * '\u0080' - '\u00FF'. + * 0x0080 - 0x00FF. */ public static final UnicodeBlock LATIN_1_SUPPLEMENT - = new UnicodeBlock('\u0080', '\u00FF', - "LATIN_1_SUPPLEMENT"); + = new UnicodeBlock(0x0080, 0x00FF, + "LATIN_1_SUPPLEMENT", + "Latin-1 Supplement"); /** * Latin Extended-A. - * '\u0100' - '\u017F'. + * 0x0100 - 0x017F. */ public static final UnicodeBlock LATIN_EXTENDED_A - = new UnicodeBlock('\u0100', '\u017F', - "LATIN_EXTENDED_A"); + = new UnicodeBlock(0x0100, 0x017F, + "LATIN_EXTENDED_A", + "Latin Extended-A"); /** * Latin Extended-B. - * '\u0180' - '\u024F'. + * 0x0180 - 0x024F. */ public static final UnicodeBlock LATIN_EXTENDED_B - = new UnicodeBlock('\u0180', '\u024F', - "LATIN_EXTENDED_B"); + = new UnicodeBlock(0x0180, 0x024F, + "LATIN_EXTENDED_B", + "Latin Extended-B"); /** * IPA Extensions. - * '\u0250' - '\u02AF'. + * 0x0250 - 0x02AF. */ public static final UnicodeBlock IPA_EXTENSIONS - = new UnicodeBlock('\u0250', '\u02AF', - "IPA_EXTENSIONS"); + = new UnicodeBlock(0x0250, 0x02AF, + "IPA_EXTENSIONS", + "IPA Extensions"); /** * Spacing Modifier Letters. - * '\u02B0' - '\u02FF'. + * 0x02B0 - 0x02FF. */ public static final UnicodeBlock SPACING_MODIFIER_LETTERS - = new UnicodeBlock('\u02B0', '\u02FF', - "SPACING_MODIFIER_LETTERS"); + = new UnicodeBlock(0x02B0, 0x02FF, + "SPACING_MODIFIER_LETTERS", + "Spacing Modifier Letters"); /** * Combining Diacritical Marks. - * '\u0300' - '\u036F'. + * 0x0300 - 0x036F. */ public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS - = new UnicodeBlock('\u0300', '\u036F', - "COMBINING_DIACRITICAL_MARKS"); + = new UnicodeBlock(0x0300, 0x036F, + "COMBINING_DIACRITICAL_MARKS", + "Combining Diacritical Marks"); /** * Greek. - * '\u0370' - '\u03FF'. + * 0x0370 - 0x03FF. */ public static final UnicodeBlock GREEK - = new UnicodeBlock('\u0370', '\u03FF', - "GREEK"); + = new UnicodeBlock(0x0370, 0x03FF, + "GREEK", + "Greek"); /** * Cyrillic. - * '\u0400' - '\u04FF'. + * 0x0400 - 0x04FF. */ public static final UnicodeBlock CYRILLIC - = new UnicodeBlock('\u0400', '\u04FF', - "CYRILLIC"); + = new UnicodeBlock(0x0400, 0x04FF, + "CYRILLIC", + "Cyrillic"); + + /** + * Cyrillic Supplementary. + * 0x0500 - 0x052F. + * @since 1.5 + */ + public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY + = new UnicodeBlock(0x0500, 0x052F, + "CYRILLIC_SUPPLEMENTARY", + "Cyrillic Supplementary"); /** * Armenian. - * '\u0530' - '\u058F'. + * 0x0530 - 0x058F. */ public static final UnicodeBlock ARMENIAN - = new UnicodeBlock('\u0530', '\u058F', - "ARMENIAN"); + = new UnicodeBlock(0x0530, 0x058F, + "ARMENIAN", + "Armenian"); /** * Hebrew. - * '\u0590' - '\u05FF'. + * 0x0590 - 0x05FF. */ public static final UnicodeBlock HEBREW - = new UnicodeBlock('\u0590', '\u05FF', - "HEBREW"); + = new UnicodeBlock(0x0590, 0x05FF, + "HEBREW", + "Hebrew"); /** * Arabic. - * '\u0600' - '\u06FF'. + * 0x0600 - 0x06FF. */ public static final UnicodeBlock ARABIC - = new UnicodeBlock('\u0600', '\u06FF', - "ARABIC"); + = new UnicodeBlock(0x0600, 0x06FF, + "ARABIC", + "Arabic"); /** * Syriac. - * '\u0700' - '\u074F'. + * 0x0700 - 0x074F. * @since 1.4 */ public static final UnicodeBlock SYRIAC - = new UnicodeBlock('\u0700', '\u074F', - "SYRIAC"); + = new UnicodeBlock(0x0700, 0x074F, + "SYRIAC", + "Syriac"); /** * Thaana. - * '\u0780' - '\u07BF'. + * 0x0780 - 0x07BF. * @since 1.4 */ public static final UnicodeBlock THAANA - = new UnicodeBlock('\u0780', '\u07BF', - "THAANA"); + = new UnicodeBlock(0x0780, 0x07BF, + "THAANA", + "Thaana"); /** * Devanagari. - * '\u0900' - '\u097F'. + * 0x0900 - 0x097F. */ public static final UnicodeBlock DEVANAGARI - = new UnicodeBlock('\u0900', '\u097F', - "DEVANAGARI"); + = new UnicodeBlock(0x0900, 0x097F, + "DEVANAGARI", + "Devanagari"); /** * Bengali. - * '\u0980' - '\u09FF'. + * 0x0980 - 0x09FF. */ public static final UnicodeBlock BENGALI - = new UnicodeBlock('\u0980', '\u09FF', - "BENGALI"); + = new UnicodeBlock(0x0980, 0x09FF, + "BENGALI", + "Bengali"); /** * Gurmukhi. - * '\u0A00' - '\u0A7F'. + * 0x0A00 - 0x0A7F. */ public static final UnicodeBlock GURMUKHI - = new UnicodeBlock('\u0A00', '\u0A7F', - "GURMUKHI"); + = new UnicodeBlock(0x0A00, 0x0A7F, + "GURMUKHI", + "Gurmukhi"); /** * Gujarati. - * '\u0A80' - '\u0AFF'. + * 0x0A80 - 0x0AFF. */ public static final UnicodeBlock GUJARATI - = new UnicodeBlock('\u0A80', '\u0AFF', - "GUJARATI"); + = new UnicodeBlock(0x0A80, 0x0AFF, + "GUJARATI", + "Gujarati"); /** * Oriya. - * '\u0B00' - '\u0B7F'. + * 0x0B00 - 0x0B7F. */ public static final UnicodeBlock ORIYA - = new UnicodeBlock('\u0B00', '\u0B7F', - "ORIYA"); + = new UnicodeBlock(0x0B00, 0x0B7F, + "ORIYA", + "Oriya"); /** * Tamil. - * '\u0B80' - '\u0BFF'. + * 0x0B80 - 0x0BFF. */ public static final UnicodeBlock TAMIL - = new UnicodeBlock('\u0B80', '\u0BFF', - "TAMIL"); + = new UnicodeBlock(0x0B80, 0x0BFF, + "TAMIL", + "Tamil"); /** * Telugu. - * '\u0C00' - '\u0C7F'. + * 0x0C00 - 0x0C7F. */ public static final UnicodeBlock TELUGU - = new UnicodeBlock('\u0C00', '\u0C7F', - "TELUGU"); + = new UnicodeBlock(0x0C00, 0x0C7F, + "TELUGU", + "Telugu"); /** * Kannada. - * '\u0C80' - '\u0CFF'. + * 0x0C80 - 0x0CFF. */ public static final UnicodeBlock KANNADA - = new UnicodeBlock('\u0C80', '\u0CFF', - "KANNADA"); + = new UnicodeBlock(0x0C80, 0x0CFF, + "KANNADA", + "Kannada"); /** * Malayalam. - * '\u0D00' - '\u0D7F'. + * 0x0D00 - 0x0D7F. */ public static final UnicodeBlock MALAYALAM - = new UnicodeBlock('\u0D00', '\u0D7F', - "MALAYALAM"); + = new UnicodeBlock(0x0D00, 0x0D7F, + "MALAYALAM", + "Malayalam"); /** * Sinhala. - * '\u0D80' - '\u0DFF'. + * 0x0D80 - 0x0DFF. * @since 1.4 */ public static final UnicodeBlock SINHALA - = new UnicodeBlock('\u0D80', '\u0DFF', - "SINHALA"); + = new UnicodeBlock(0x0D80, 0x0DFF, + "SINHALA", + "Sinhala"); /** * Thai. - * '\u0E00' - '\u0E7F'. + * 0x0E00 - 0x0E7F. */ public static final UnicodeBlock THAI - = new UnicodeBlock('\u0E00', '\u0E7F', - "THAI"); + = new UnicodeBlock(0x0E00, 0x0E7F, + "THAI", + "Thai"); /** * Lao. - * '\u0E80' - '\u0EFF'. + * 0x0E80 - 0x0EFF. */ public static final UnicodeBlock LAO - = new UnicodeBlock('\u0E80', '\u0EFF', - "LAO"); + = new UnicodeBlock(0x0E80, 0x0EFF, + "LAO", + "Lao"); /** * Tibetan. - * '\u0F00' - '\u0FFF'. + * 0x0F00 - 0x0FFF. */ public static final UnicodeBlock TIBETAN - = new UnicodeBlock('\u0F00', '\u0FFF', - "TIBETAN"); + = new UnicodeBlock(0x0F00, 0x0FFF, + "TIBETAN", + "Tibetan"); /** * Myanmar. - * '\u1000' - '\u109F'. + * 0x1000 - 0x109F. * @since 1.4 */ public static final UnicodeBlock MYANMAR - = new UnicodeBlock('\u1000', '\u109F', - "MYANMAR"); + = new UnicodeBlock(0x1000, 0x109F, + "MYANMAR", + "Myanmar"); /** * Georgian. - * '\u10A0' - '\u10FF'. + * 0x10A0 - 0x10FF. */ public static final UnicodeBlock GEORGIAN - = new UnicodeBlock('\u10A0', '\u10FF', - "GEORGIAN"); + = new UnicodeBlock(0x10A0, 0x10FF, + "GEORGIAN", + "Georgian"); /** * Hangul Jamo. - * '\u1100' - '\u11FF'. + * 0x1100 - 0x11FF. */ public static final UnicodeBlock HANGUL_JAMO - = new UnicodeBlock('\u1100', '\u11FF', - "HANGUL_JAMO"); + = new UnicodeBlock(0x1100, 0x11FF, + "HANGUL_JAMO", + "Hangul Jamo"); /** * Ethiopic. - * '\u1200' - '\u137F'. + * 0x1200 - 0x137F. * @since 1.4 */ public static final UnicodeBlock ETHIOPIC - = new UnicodeBlock('\u1200', '\u137F', - "ETHIOPIC"); + = new UnicodeBlock(0x1200, 0x137F, + "ETHIOPIC", + "Ethiopic"); /** * Cherokee. - * '\u13A0' - '\u13FF'. + * 0x13A0 - 0x13FF. * @since 1.4 */ public static final UnicodeBlock CHEROKEE - = new UnicodeBlock('\u13A0', '\u13FF', - "CHEROKEE"); + = new UnicodeBlock(0x13A0, 0x13FF, + "CHEROKEE", + "Cherokee"); /** * Unified Canadian Aboriginal Syllabics. - * '\u1400' - '\u167F'. + * 0x1400 - 0x167F. * @since 1.4 */ public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS - = new UnicodeBlock('\u1400', '\u167F', - "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS"); + = new UnicodeBlock(0x1400, 0x167F, + "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS", + "Unified Canadian Aboriginal Syllabics"); /** * Ogham. - * '\u1680' - '\u169F'. + * 0x1680 - 0x169F. * @since 1.4 */ public static final UnicodeBlock OGHAM - = new UnicodeBlock('\u1680', '\u169F', - "OGHAM"); + = new UnicodeBlock(0x1680, 0x169F, + "OGHAM", + "Ogham"); /** * Runic. - * '\u16A0' - '\u16FF'. + * 0x16A0 - 0x16FF. * @since 1.4 */ public static final UnicodeBlock RUNIC - = new UnicodeBlock('\u16A0', '\u16FF', - "RUNIC"); + = new UnicodeBlock(0x16A0, 0x16FF, + "RUNIC", + "Runic"); + + /** + * Tagalog. + * 0x1700 - 0x171F. + * @since 1.5 + */ + public static final UnicodeBlock TAGALOG + = new UnicodeBlock(0x1700, 0x171F, + "TAGALOG", + "Tagalog"); + + /** + * Hanunoo. + * 0x1720 - 0x173F. + * @since 1.5 + */ + public static final UnicodeBlock HANUNOO + = new UnicodeBlock(0x1720, 0x173F, + "HANUNOO", + "Hanunoo"); + + /** + * Buhid. + * 0x1740 - 0x175F. + * @since 1.5 + */ + public static final UnicodeBlock BUHID + = new UnicodeBlock(0x1740, 0x175F, + "BUHID", + "Buhid"); + + /** + * Tagbanwa. + * 0x1760 - 0x177F. + * @since 1.5 + */ + public static final UnicodeBlock TAGBANWA + = new UnicodeBlock(0x1760, 0x177F, + "TAGBANWA", + "Tagbanwa"); /** * Khmer. - * '\u1780' - '\u17FF'. + * 0x1780 - 0x17FF. * @since 1.4 */ public static final UnicodeBlock KHMER - = new UnicodeBlock('\u1780', '\u17FF', - "KHMER"); + = new UnicodeBlock(0x1780, 0x17FF, + "KHMER", + "Khmer"); /** * Mongolian. - * '\u1800' - '\u18AF'. + * 0x1800 - 0x18AF. * @since 1.4 */ public static final UnicodeBlock MONGOLIAN - = new UnicodeBlock('\u1800', '\u18AF', - "MONGOLIAN"); + = new UnicodeBlock(0x1800, 0x18AF, + "MONGOLIAN", + "Mongolian"); + + /** + * Limbu. + * 0x1900 - 0x194F. + * @since 1.5 + */ + public static final UnicodeBlock LIMBU + = new UnicodeBlock(0x1900, 0x194F, + "LIMBU", + "Limbu"); + + /** + * Tai Le. + * 0x1950 - 0x197F. + * @since 1.5 + */ + public static final UnicodeBlock TAI_LE + = new UnicodeBlock(0x1950, 0x197F, + "TAI_LE", + "Tai Le"); + + /** + * Khmer Symbols. + * 0x19E0 - 0x19FF. + * @since 1.5 + */ + public static final UnicodeBlock KHMER_SYMBOLS + = new UnicodeBlock(0x19E0, 0x19FF, + "KHMER_SYMBOLS", + "Khmer Symbols"); + + /** + * Phonetic Extensions. + * 0x1D00 - 0x1D7F. + * @since 1.5 + */ + public static final UnicodeBlock PHONETIC_EXTENSIONS + = new UnicodeBlock(0x1D00, 0x1D7F, + "PHONETIC_EXTENSIONS", + "Phonetic Extensions"); /** * Latin Extended Additional. - * '\u1E00' - '\u1EFF'. + * 0x1E00 - 0x1EFF. */ public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL - = new UnicodeBlock('\u1E00', '\u1EFF', - "LATIN_EXTENDED_ADDITIONAL"); + = new UnicodeBlock(0x1E00, 0x1EFF, + "LATIN_EXTENDED_ADDITIONAL", + "Latin Extended Additional"); /** * Greek Extended. - * '\u1F00' - '\u1FFF'. + * 0x1F00 - 0x1FFF. */ public static final UnicodeBlock GREEK_EXTENDED - = new UnicodeBlock('\u1F00', '\u1FFF', - "GREEK_EXTENDED"); + = new UnicodeBlock(0x1F00, 0x1FFF, + "GREEK_EXTENDED", + "Greek Extended"); /** * General Punctuation. - * '\u2000' - '\u206F'. + * 0x2000 - 0x206F. */ public static final UnicodeBlock GENERAL_PUNCTUATION - = new UnicodeBlock('\u2000', '\u206F', - "GENERAL_PUNCTUATION"); + = new UnicodeBlock(0x2000, 0x206F, + "GENERAL_PUNCTUATION", + "General Punctuation"); /** * Superscripts and Subscripts. - * '\u2070' - '\u209F'. + * 0x2070 - 0x209F. */ public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS - = new UnicodeBlock('\u2070', '\u209F', - "SUPERSCRIPTS_AND_SUBSCRIPTS"); + = new UnicodeBlock(0x2070, 0x209F, + "SUPERSCRIPTS_AND_SUBSCRIPTS", + "Superscripts and Subscripts"); /** * Currency Symbols. - * '\u20A0' - '\u20CF'. + * 0x20A0 - 0x20CF. */ public static final UnicodeBlock CURRENCY_SYMBOLS - = new UnicodeBlock('\u20A0', '\u20CF', - "CURRENCY_SYMBOLS"); + = new UnicodeBlock(0x20A0, 0x20CF, + "CURRENCY_SYMBOLS", + "Currency Symbols"); /** * Combining Marks for Symbols. - * '\u20D0' - '\u20FF'. + * 0x20D0 - 0x20FF. */ public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS - = new UnicodeBlock('\u20D0', '\u20FF', - "COMBINING_MARKS_FOR_SYMBOLS"); + = new UnicodeBlock(0x20D0, 0x20FF, + "COMBINING_MARKS_FOR_SYMBOLS", + "Combining Marks for Symbols"); /** * Letterlike Symbols. - * '\u2100' - '\u214F'. + * 0x2100 - 0x214F. */ public static final UnicodeBlock LETTERLIKE_SYMBOLS - = new UnicodeBlock('\u2100', '\u214F', - "LETTERLIKE_SYMBOLS"); + = new UnicodeBlock(0x2100, 0x214F, + "LETTERLIKE_SYMBOLS", + "Letterlike Symbols"); /** * Number Forms. - * '\u2150' - '\u218F'. + * 0x2150 - 0x218F. */ public static final UnicodeBlock NUMBER_FORMS - = new UnicodeBlock('\u2150', '\u218F', - "NUMBER_FORMS"); + = new UnicodeBlock(0x2150, 0x218F, + "NUMBER_FORMS", + "Number Forms"); /** * Arrows. - * '\u2190' - '\u21FF'. + * 0x2190 - 0x21FF. */ public static final UnicodeBlock ARROWS - = new UnicodeBlock('\u2190', '\u21FF', - "ARROWS"); + = new UnicodeBlock(0x2190, 0x21FF, + "ARROWS", + "Arrows"); /** * Mathematical Operators. - * '\u2200' - '\u22FF'. + * 0x2200 - 0x22FF. */ public static final UnicodeBlock MATHEMATICAL_OPERATORS - = new UnicodeBlock('\u2200', '\u22FF', - "MATHEMATICAL_OPERATORS"); + = new UnicodeBlock(0x2200, 0x22FF, + "MATHEMATICAL_OPERATORS", + "Mathematical Operators"); /** * Miscellaneous Technical. - * '\u2300' - '\u23FF'. + * 0x2300 - 0x23FF. */ public static final UnicodeBlock MISCELLANEOUS_TECHNICAL - = new UnicodeBlock('\u2300', '\u23FF', - "MISCELLANEOUS_TECHNICAL"); + = new UnicodeBlock(0x2300, 0x23FF, + "MISCELLANEOUS_TECHNICAL", + "Miscellaneous Technical"); /** * Control Pictures. - * '\u2400' - '\u243F'. + * 0x2400 - 0x243F. */ public static final UnicodeBlock CONTROL_PICTURES - = new UnicodeBlock('\u2400', '\u243F', - "CONTROL_PICTURES"); + = new UnicodeBlock(0x2400, 0x243F, + "CONTROL_PICTURES", + "Control Pictures"); /** * Optical Character Recognition. - * '\u2440' - '\u245F'. + * 0x2440 - 0x245F. */ public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION - = new UnicodeBlock('\u2440', '\u245F', - "OPTICAL_CHARACTER_RECOGNITION"); + = new UnicodeBlock(0x2440, 0x245F, + "OPTICAL_CHARACTER_RECOGNITION", + "Optical Character Recognition"); /** * Enclosed Alphanumerics. - * '\u2460' - '\u24FF'. + * 0x2460 - 0x24FF. */ public static final UnicodeBlock ENCLOSED_ALPHANUMERICS - = new UnicodeBlock('\u2460', '\u24FF', - "ENCLOSED_ALPHANUMERICS"); + = new UnicodeBlock(0x2460, 0x24FF, + "ENCLOSED_ALPHANUMERICS", + "Enclosed Alphanumerics"); /** * Box Drawing. - * '\u2500' - '\u257F'. + * 0x2500 - 0x257F. */ public static final UnicodeBlock BOX_DRAWING - = new UnicodeBlock('\u2500', '\u257F', - "BOX_DRAWING"); + = new UnicodeBlock(0x2500, 0x257F, + "BOX_DRAWING", + "Box Drawing"); /** * Block Elements. - * '\u2580' - '\u259F'. + * 0x2580 - 0x259F. */ public static final UnicodeBlock BLOCK_ELEMENTS - = new UnicodeBlock('\u2580', '\u259F', - "BLOCK_ELEMENTS"); + = new UnicodeBlock(0x2580, 0x259F, + "BLOCK_ELEMENTS", + "Block Elements"); /** * Geometric Shapes. - * '\u25A0' - '\u25FF'. + * 0x25A0 - 0x25FF. */ public static final UnicodeBlock GEOMETRIC_SHAPES - = new UnicodeBlock('\u25A0', '\u25FF', - "GEOMETRIC_SHAPES"); + = new UnicodeBlock(0x25A0, 0x25FF, + "GEOMETRIC_SHAPES", + "Geometric Shapes"); /** * Miscellaneous Symbols. - * '\u2600' - '\u26FF'. + * 0x2600 - 0x26FF. */ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS - = new UnicodeBlock('\u2600', '\u26FF', - "MISCELLANEOUS_SYMBOLS"); + = new UnicodeBlock(0x2600, 0x26FF, + "MISCELLANEOUS_SYMBOLS", + "Miscellaneous Symbols"); /** * Dingbats. - * '\u2700' - '\u27BF'. + * 0x2700 - 0x27BF. */ public static final UnicodeBlock DINGBATS - = new UnicodeBlock('\u2700', '\u27BF', - "DINGBATS"); + = new UnicodeBlock(0x2700, 0x27BF, + "DINGBATS", + "Dingbats"); + + /** + * Miscellaneous Mathematical Symbols-A. + * 0x27C0 - 0x27EF. + * @since 1.5 + */ + public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A + = new UnicodeBlock(0x27C0, 0x27EF, + "MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A", + "Miscellaneous Mathematical Symbols-A"); + + /** + * Supplemental Arrows-A. + * 0x27F0 - 0x27FF. + * @since 1.5 + */ + public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A + = new UnicodeBlock(0x27F0, 0x27FF, + "SUPPLEMENTAL_ARROWS_A", + "Supplemental Arrows-A"); /** * Braille Patterns. - * '\u2800' - '\u28FF'. + * 0x2800 - 0x28FF. * @since 1.4 */ public static final UnicodeBlock BRAILLE_PATTERNS - = new UnicodeBlock('\u2800', '\u28FF', - "BRAILLE_PATTERNS"); + = new UnicodeBlock(0x2800, 0x28FF, + "BRAILLE_PATTERNS", + "Braille Patterns"); + + /** + * Supplemental Arrows-B. + * 0x2900 - 0x297F. + * @since 1.5 + */ + public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B + = new UnicodeBlock(0x2900, 0x297F, + "SUPPLEMENTAL_ARROWS_B", + "Supplemental Arrows-B"); + + /** + * Miscellaneous Mathematical Symbols-B. + * 0x2980 - 0x29FF. + * @since 1.5 + */ + public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B + = new UnicodeBlock(0x2980, 0x29FF, + "MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B", + "Miscellaneous Mathematical Symbols-B"); + + /** + * Supplemental Mathematical Operators. + * 0x2A00 - 0x2AFF. + * @since 1.5 + */ + public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS + = new UnicodeBlock(0x2A00, 0x2AFF, + "SUPPLEMENTAL_MATHEMATICAL_OPERATORS", + "Supplemental Mathematical Operators"); + + /** + * Miscellaneous Symbols and Arrows. + * 0x2B00 - 0x2BFF. + * @since 1.5 + */ + public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS + = new UnicodeBlock(0x2B00, 0x2BFF, + "MISCELLANEOUS_SYMBOLS_AND_ARROWS", + "Miscellaneous Symbols and Arrows"); /** * CJK Radicals Supplement. - * '\u2E80' - '\u2EFF'. + * 0x2E80 - 0x2EFF. * @since 1.4 */ public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT - = new UnicodeBlock('\u2E80', '\u2EFF', - "CJK_RADICALS_SUPPLEMENT"); + = new UnicodeBlock(0x2E80, 0x2EFF, + "CJK_RADICALS_SUPPLEMENT", + "CJK Radicals Supplement"); /** * Kangxi Radicals. - * '\u2F00' - '\u2FDF'. + * 0x2F00 - 0x2FDF. * @since 1.4 */ public static final UnicodeBlock KANGXI_RADICALS - = new UnicodeBlock('\u2F00', '\u2FDF', - "KANGXI_RADICALS"); + = new UnicodeBlock(0x2F00, 0x2FDF, + "KANGXI_RADICALS", + "Kangxi Radicals"); /** * Ideographic Description Characters. - * '\u2FF0' - '\u2FFF'. + * 0x2FF0 - 0x2FFF. * @since 1.4 */ public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS - = new UnicodeBlock('\u2FF0', '\u2FFF', - "IDEOGRAPHIC_DESCRIPTION_CHARACTERS"); + = new UnicodeBlock(0x2FF0, 0x2FFF, + "IDEOGRAPHIC_DESCRIPTION_CHARACTERS", + "Ideographic Description Characters"); /** * CJK Symbols and Punctuation. - * '\u3000' - '\u303F'. + * 0x3000 - 0x303F. */ public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION - = new UnicodeBlock('\u3000', '\u303F', - "CJK_SYMBOLS_AND_PUNCTUATION"); + = new UnicodeBlock(0x3000, 0x303F, + "CJK_SYMBOLS_AND_PUNCTUATION", + "CJK Symbols and Punctuation"); /** * Hiragana. - * '\u3040' - '\u309F'. + * 0x3040 - 0x309F. */ public static final UnicodeBlock HIRAGANA - = new UnicodeBlock('\u3040', '\u309F', - "HIRAGANA"); + = new UnicodeBlock(0x3040, 0x309F, + "HIRAGANA", + "Hiragana"); /** * Katakana. - * '\u30A0' - '\u30FF'. + * 0x30A0 - 0x30FF. */ public static final UnicodeBlock KATAKANA - = new UnicodeBlock('\u30A0', '\u30FF', - "KATAKANA"); + = new UnicodeBlock(0x30A0, 0x30FF, + "KATAKANA", + "Katakana"); /** * Bopomofo. - * '\u3100' - '\u312F'. + * 0x3100 - 0x312F. */ public static final UnicodeBlock BOPOMOFO - = new UnicodeBlock('\u3100', '\u312F', - "BOPOMOFO"); + = new UnicodeBlock(0x3100, 0x312F, + "BOPOMOFO", + "Bopomofo"); /** * Hangul Compatibility Jamo. - * '\u3130' - '\u318F'. + * 0x3130 - 0x318F. */ public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO - = new UnicodeBlock('\u3130', '\u318F', - "HANGUL_COMPATIBILITY_JAMO"); + = new UnicodeBlock(0x3130, 0x318F, + "HANGUL_COMPATIBILITY_JAMO", + "Hangul Compatibility Jamo"); /** * Kanbun. - * '\u3190' - '\u319F'. + * 0x3190 - 0x319F. */ public static final UnicodeBlock KANBUN - = new UnicodeBlock('\u3190', '\u319F', - "KANBUN"); + = new UnicodeBlock(0x3190, 0x319F, + "KANBUN", + "Kanbun"); /** * Bopomofo Extended. - * '\u31A0' - '\u31BF'. + * 0x31A0 - 0x31BF. * @since 1.4 */ public static final UnicodeBlock BOPOMOFO_EXTENDED - = new UnicodeBlock('\u31A0', '\u31BF', - "BOPOMOFO_EXTENDED"); + = new UnicodeBlock(0x31A0, 0x31BF, + "BOPOMOFO_EXTENDED", + "Bopomofo Extended"); + + /** + * Katakana Phonetic Extensions. + * 0x31F0 - 0x31FF. + * @since 1.5 + */ + public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS + = new UnicodeBlock(0x31F0, 0x31FF, + "KATAKANA_PHONETIC_EXTENSIONS", + "Katakana Phonetic Extensions"); /** * Enclosed CJK Letters and Months. - * '\u3200' - '\u32FF'. + * 0x3200 - 0x32FF. */ public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS - = new UnicodeBlock('\u3200', '\u32FF', - "ENCLOSED_CJK_LETTERS_AND_MONTHS"); + = new UnicodeBlock(0x3200, 0x32FF, + "ENCLOSED_CJK_LETTERS_AND_MONTHS", + "Enclosed CJK Letters and Months"); /** * CJK Compatibility. - * '\u3300' - '\u33FF'. + * 0x3300 - 0x33FF. */ public static final UnicodeBlock CJK_COMPATIBILITY - = new UnicodeBlock('\u3300', '\u33FF', - "CJK_COMPATIBILITY"); + = new UnicodeBlock(0x3300, 0x33FF, + "CJK_COMPATIBILITY", + "CJK Compatibility"); /** * CJK Unified Ideographs Extension A. - * '\u3400' - '\u4DB5'. + * 0x3400 - 0x4DBF. * @since 1.4 */ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A - = new UnicodeBlock('\u3400', '\u4DB5', - "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A"); + = new UnicodeBlock(0x3400, 0x4DBF, + "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A", + "CJK Unified Ideographs Extension A"); + + /** + * Yijing Hexagram Symbols. + * 0x4DC0 - 0x4DFF. + * @since 1.5 + */ + public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS + = new UnicodeBlock(0x4DC0, 0x4DFF, + "YIJING_HEXAGRAM_SYMBOLS", + "Yijing Hexagram Symbols"); /** * CJK Unified Ideographs. - * '\u4E00' - '\u9FFF'. + * 0x4E00 - 0x9FFF. */ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS - = new UnicodeBlock('\u4E00', '\u9FFF', - "CJK_UNIFIED_IDEOGRAPHS"); + = new UnicodeBlock(0x4E00, 0x9FFF, + "CJK_UNIFIED_IDEOGRAPHS", + "CJK Unified Ideographs"); /** * Yi Syllables. - * '\uA000' - '\uA48F'. + * 0xA000 - 0xA48F. * @since 1.4 */ public static final UnicodeBlock YI_SYLLABLES - = new UnicodeBlock('\uA000', '\uA48F', - "YI_SYLLABLES"); + = new UnicodeBlock(0xA000, 0xA48F, + "YI_SYLLABLES", + "Yi Syllables"); /** * Yi Radicals. - * '\uA490' - '\uA4CF'. + * 0xA490 - 0xA4CF. * @since 1.4 */ public static final UnicodeBlock YI_RADICALS - = new UnicodeBlock('\uA490', '\uA4CF', - "YI_RADICALS"); + = new UnicodeBlock(0xA490, 0xA4CF, + "YI_RADICALS", + "Yi Radicals"); /** * Hangul Syllables. - * '\uAC00' - '\uD7A3'. + * 0xAC00 - 0xD7AF. */ public static final UnicodeBlock HANGUL_SYLLABLES - = new UnicodeBlock('\uAC00', '\uD7A3', - "HANGUL_SYLLABLES"); + = new UnicodeBlock(0xAC00, 0xD7AF, + "HANGUL_SYLLABLES", + "Hangul Syllables"); /** - * Surrogates Area. - * '\uD800' - '\uDFFF'. + * High Surrogates. + * 0xD800 - 0xDB7F. + * @since 1.5 */ - public static final UnicodeBlock SURROGATES_AREA - = new UnicodeBlock('\uD800', '\uDFFF', - "SURROGATES_AREA"); + public static final UnicodeBlock HIGH_SURROGATES + = new UnicodeBlock(0xD800, 0xDB7F, + "HIGH_SURROGATES", + "High Surrogates"); + + /** + * High Private Use Surrogates. + * 0xDB80 - 0xDBFF. + * @since 1.5 + */ + public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES + = new UnicodeBlock(0xDB80, 0xDBFF, + "HIGH_PRIVATE_USE_SURROGATES", + "High Private Use Surrogates"); + + /** + * Low Surrogates. + * 0xDC00 - 0xDFFF. + * @since 1.5 + */ + public static final UnicodeBlock LOW_SURROGATES + = new UnicodeBlock(0xDC00, 0xDFFF, + "LOW_SURROGATES", + "Low Surrogates"); /** * Private Use Area. - * '\uE000' - '\uF8FF'. + * 0xE000 - 0xF8FF. */ public static final UnicodeBlock PRIVATE_USE_AREA - = new UnicodeBlock('\uE000', '\uF8FF', - "PRIVATE_USE_AREA"); + = new UnicodeBlock(0xE000, 0xF8FF, + "PRIVATE_USE_AREA", + "Private Use Area"); /** * CJK Compatibility Ideographs. - * '\uF900' - '\uFAFF'. + * 0xF900 - 0xFAFF. */ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS - = new UnicodeBlock('\uF900', '\uFAFF', - "CJK_COMPATIBILITY_IDEOGRAPHS"); + = new UnicodeBlock(0xF900, 0xFAFF, + "CJK_COMPATIBILITY_IDEOGRAPHS", + "CJK Compatibility Ideographs"); /** * Alphabetic Presentation Forms. - * '\uFB00' - '\uFB4F'. + * 0xFB00 - 0xFB4F. */ public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS - = new UnicodeBlock('\uFB00', '\uFB4F', - "ALPHABETIC_PRESENTATION_FORMS"); + = new UnicodeBlock(0xFB00, 0xFB4F, + "ALPHABETIC_PRESENTATION_FORMS", + "Alphabetic Presentation Forms"); /** * Arabic Presentation Forms-A. - * '\uFB50' - '\uFDFF'. + * 0xFB50 - 0xFDFF. */ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A - = new UnicodeBlock('\uFB50', '\uFDFF', - "ARABIC_PRESENTATION_FORMS_A"); + = new UnicodeBlock(0xFB50, 0xFDFF, + "ARABIC_PRESENTATION_FORMS_A", + "Arabic Presentation Forms-A"); + + /** + * Variation Selectors. + * 0xFE00 - 0xFE0F. + * @since 1.5 + */ + public static final UnicodeBlock VARIATION_SELECTORS + = new UnicodeBlock(0xFE00, 0xFE0F, + "VARIATION_SELECTORS", + "Variation Selectors"); /** * Combining Half Marks. - * '\uFE20' - '\uFE2F'. + * 0xFE20 - 0xFE2F. */ public static final UnicodeBlock COMBINING_HALF_MARKS - = new UnicodeBlock('\uFE20', '\uFE2F', - "COMBINING_HALF_MARKS"); + = new UnicodeBlock(0xFE20, 0xFE2F, + "COMBINING_HALF_MARKS", + "Combining Half Marks"); /** * CJK Compatibility Forms. - * '\uFE30' - '\uFE4F'. + * 0xFE30 - 0xFE4F. */ public static final UnicodeBlock CJK_COMPATIBILITY_FORMS - = new UnicodeBlock('\uFE30', '\uFE4F', - "CJK_COMPATIBILITY_FORMS"); + = new UnicodeBlock(0xFE30, 0xFE4F, + "CJK_COMPATIBILITY_FORMS", + "CJK Compatibility Forms"); /** * Small Form Variants. - * '\uFE50' - '\uFE6F'. + * 0xFE50 - 0xFE6F. */ public static final UnicodeBlock SMALL_FORM_VARIANTS - = new UnicodeBlock('\uFE50', '\uFE6F', - "SMALL_FORM_VARIANTS"); + = new UnicodeBlock(0xFE50, 0xFE6F, + "SMALL_FORM_VARIANTS", + "Small Form Variants"); /** * Arabic Presentation Forms-B. - * '\uFE70' - '\uFEFE'. + * 0xFE70 - 0xFEFF. */ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B - = new UnicodeBlock('\uFE70', '\uFEFE', - "ARABIC_PRESENTATION_FORMS_B"); + = new UnicodeBlock(0xFE70, 0xFEFF, + "ARABIC_PRESENTATION_FORMS_B", + "Arabic Presentation Forms-B"); /** * Halfwidth and Fullwidth Forms. - * '\uFF00' - '\uFFEF'. + * 0xFF00 - 0xFFEF. */ public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS - = new UnicodeBlock('\uFF00', '\uFFEF', - "HALFWIDTH_AND_FULLWIDTH_FORMS"); + = new UnicodeBlock(0xFF00, 0xFFEF, + "HALFWIDTH_AND_FULLWIDTH_FORMS", + "Halfwidth and Fullwidth Forms"); /** * Specials. - * '\uFEFF', '\uFFF0' - '\uFFFD'. + * 0xFFF0 - 0xFFFF. */ public static final UnicodeBlock SPECIALS - = new UnicodeBlock('\uFFF0', '\uFFFD', - "SPECIALS"); + = new UnicodeBlock(0xFFF0, 0xFFFF, + "SPECIALS", + "Specials"); + + /** + * Linear B Syllabary. + * 0x10000 - 0x1007F. + * @since 1.5 + */ + public static final UnicodeBlock LINEAR_B_SYLLABARY + = new UnicodeBlock(0x10000, 0x1007F, + "LINEAR_B_SYLLABARY", + "Linear B Syllabary"); + + /** + * Linear B Ideograms. + * 0x10080 - 0x100FF. + * @since 1.5 + */ + public static final UnicodeBlock LINEAR_B_IDEOGRAMS + = new UnicodeBlock(0x10080, 0x100FF, + "LINEAR_B_IDEOGRAMS", + "Linear B Ideograms"); + + /** + * Aegean Numbers. + * 0x10100 - 0x1013F. + * @since 1.5 + */ + public static final UnicodeBlock AEGEAN_NUMBERS + = new UnicodeBlock(0x10100, 0x1013F, + "AEGEAN_NUMBERS", + "Aegean Numbers"); + + /** + * Old Italic. + * 0x10300 - 0x1032F. + * @since 1.5 + */ + public static final UnicodeBlock OLD_ITALIC + = new UnicodeBlock(0x10300, 0x1032F, + "OLD_ITALIC", + "Old Italic"); + + /** + * Gothic. + * 0x10330 - 0x1034F. + * @since 1.5 + */ + public static final UnicodeBlock GOTHIC + = new UnicodeBlock(0x10330, 0x1034F, + "GOTHIC", + "Gothic"); + + /** + * Ugaritic. + * 0x10380 - 0x1039F. + * @since 1.5 + */ + public static final UnicodeBlock UGARITIC + = new UnicodeBlock(0x10380, 0x1039F, + "UGARITIC", + "Ugaritic"); + + /** + * Deseret. + * 0x10400 - 0x1044F. + * @since 1.5 + */ + public static final UnicodeBlock DESERET + = new UnicodeBlock(0x10400, 0x1044F, + "DESERET", + "Deseret"); + + /** + * Shavian. + * 0x10450 - 0x1047F. + * @since 1.5 + */ + public static final UnicodeBlock SHAVIAN + = new UnicodeBlock(0x10450, 0x1047F, + "SHAVIAN", + "Shavian"); + + /** + * Osmanya. + * 0x10480 - 0x104AF. + * @since 1.5 + */ + public static final UnicodeBlock OSMANYA + = new UnicodeBlock(0x10480, 0x104AF, + "OSMANYA", + "Osmanya"); + + /** + * Cypriot Syllabary. + * 0x10800 - 0x1083F. + * @since 1.5 + */ + public static final UnicodeBlock CYPRIOT_SYLLABARY + = new UnicodeBlock(0x10800, 0x1083F, + "CYPRIOT_SYLLABARY", + "Cypriot Syllabary"); + + /** + * Byzantine Musical Symbols. + * 0x1D000 - 0x1D0FF. + * @since 1.5 + */ + public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS + = new UnicodeBlock(0x1D000, 0x1D0FF, + "BYZANTINE_MUSICAL_SYMBOLS", + "Byzantine Musical Symbols"); + + /** + * Musical Symbols. + * 0x1D100 - 0x1D1FF. + * @since 1.5 + */ + public static final UnicodeBlock MUSICAL_SYMBOLS + = new UnicodeBlock(0x1D100, 0x1D1FF, + "MUSICAL_SYMBOLS", + "Musical Symbols"); + + /** + * Tai Xuan Jing Symbols. + * 0x1D300 - 0x1D35F. + * @since 1.5 + */ + public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS + = new UnicodeBlock(0x1D300, 0x1D35F, + "TAI_XUAN_JING_SYMBOLS", + "Tai Xuan Jing Symbols"); + + /** + * Mathematical Alphanumeric Symbols. + * 0x1D400 - 0x1D7FF. + * @since 1.5 + */ + public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS + = new UnicodeBlock(0x1D400, 0x1D7FF, + "MATHEMATICAL_ALPHANUMERIC_SYMBOLS", + "Mathematical Alphanumeric Symbols"); + + /** + * CJK Unified Ideographs Extension B. + * 0x20000 - 0x2A6DF. + * @since 1.5 + */ + public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B + = new UnicodeBlock(0x20000, 0x2A6DF, + "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B", + "CJK Unified Ideographs Extension B"); + + /** + * CJK Compatibility Ideographs Supplement. + * 0x2F800 - 0x2FA1F. + * @since 1.5 + */ + public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT + = new UnicodeBlock(0x2F800, 0x2FA1F, + "CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT", + "CJK Compatibility Ideographs Supplement"); + + /** + * Tags. + * 0xE0000 - 0xE007F. + * @since 1.5 + */ + public static final UnicodeBlock TAGS + = new UnicodeBlock(0xE0000, 0xE007F, + "TAGS", + "Tags"); + + /** + * Variation Selectors Supplement. + * 0xE0100 - 0xE01EF. + * @since 1.5 + */ + public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT + = new UnicodeBlock(0xE0100, 0xE01EF, + "VARIATION_SELECTORS_SUPPLEMENT", + "Variation Selectors Supplement"); + + /** + * Supplementary Private Use Area-A. + * 0xF0000 - 0xFFFFF. + * @since 1.5 + */ + public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A + = new UnicodeBlock(0xF0000, 0xFFFFF, + "SUPPLEMENTARY_PRIVATE_USE_AREA_A", + "Supplementary Private Use Area-A"); + + /** + * Supplementary Private Use Area-B. + * 0x100000 - 0x10FFFF. + * @since 1.5 + */ + public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B + = new UnicodeBlock(0x100000, 0x10FFFF, + "SUPPLEMENTARY_PRIVATE_USE_AREA_B", + "Supplementary Private Use Area-B"); + + /** + * Surrogates Area. + * 'D800' - 'DFFF'. + * @deprecated As of 1.5, the three areas, + * <a href="#HIGH_SURROGATES">HIGH_SURROGATES</a>, + * <a href="#HIGH_PRIVATE_USE_SURROGATES">HIGH_PRIVATE_USE_SURROGATES</a> + * and <a href="#LOW_SURROGATES">LOW_SURROGATES</a>, as defined + * by the Unicode standard, should be used in preference to + * this. These are also returned from calls to <code>of(int)</code> + * and <code>of(char)</code>. + */ + public static final UnicodeBlock SURROGATES_AREA + = new UnicodeBlock(0xD800, 0xDFFF, + "SURROGATES_AREA", + "Surrogates Area"); /** * The defined subsets. @@ -903,6 +1531,7 @@ public final class Character implements Serializable, Comparable COMBINING_DIACRITICAL_MARKS, GREEK, CYRILLIC, + CYRILLIC_SUPPLEMENTARY, ARMENIAN, HEBREW, ARABIC, @@ -929,8 +1558,16 @@ public final class Character implements Serializable, Comparable UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS, OGHAM, RUNIC, + TAGALOG, + HANUNOO, + BUHID, + TAGBANWA, KHMER, MONGOLIAN, + LIMBU, + TAI_LE, + KHMER_SYMBOLS, + PHONETIC_EXTENSIONS, LATIN_EXTENDED_ADDITIONAL, GREEK_EXTENDED, GENERAL_PUNCTUATION, @@ -950,7 +1587,13 @@ public final class Character implements Serializable, Comparable GEOMETRIC_SHAPES, MISCELLANEOUS_SYMBOLS, DINGBATS, + MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A, + SUPPLEMENTAL_ARROWS_A, BRAILLE_PATTERNS, + SUPPLEMENTAL_ARROWS_B, + MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B, + SUPPLEMENTAL_MATHEMATICAL_OPERATORS, + MISCELLANEOUS_SYMBOLS_AND_ARROWS, CJK_RADICALS_SUPPLEMENT, KANGXI_RADICALS, IDEOGRAPHIC_DESCRIPTION_CHARACTERS, @@ -961,28 +1604,337 @@ public final class Character implements Serializable, Comparable HANGUL_COMPATIBILITY_JAMO, KANBUN, BOPOMOFO_EXTENDED, + KATAKANA_PHONETIC_EXTENSIONS, ENCLOSED_CJK_LETTERS_AND_MONTHS, CJK_COMPATIBILITY, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A, + YIJING_HEXAGRAM_SYMBOLS, CJK_UNIFIED_IDEOGRAPHS, YI_SYLLABLES, YI_RADICALS, HANGUL_SYLLABLES, - SURROGATES_AREA, + HIGH_SURROGATES, + HIGH_PRIVATE_USE_SURROGATES, + LOW_SURROGATES, PRIVATE_USE_AREA, CJK_COMPATIBILITY_IDEOGRAPHS, ALPHABETIC_PRESENTATION_FORMS, ARABIC_PRESENTATION_FORMS_A, + VARIATION_SELECTORS, COMBINING_HALF_MARKS, CJK_COMPATIBILITY_FORMS, SMALL_FORM_VARIANTS, ARABIC_PRESENTATION_FORMS_B, HALFWIDTH_AND_FULLWIDTH_FORMS, SPECIALS, + LINEAR_B_SYLLABARY, + LINEAR_B_IDEOGRAMS, + AEGEAN_NUMBERS, + OLD_ITALIC, + GOTHIC, + UGARITIC, + DESERET, + SHAVIAN, + OSMANYA, + CYPRIOT_SYLLABARY, + BYZANTINE_MUSICAL_SYMBOLS, + MUSICAL_SYMBOLS, + TAI_XUAN_JING_SYMBOLS, + MATHEMATICAL_ALPHANUMERIC_SYMBOLS, + CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, + CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, + TAGS, + VARIATION_SELECTORS_SUPPLEMENT, + SUPPLEMENTARY_PRIVATE_USE_AREA_A, + SUPPLEMENTARY_PRIVATE_USE_AREA_B, }; } // class UnicodeBlock /** + * A class to encompass all the properties of characters in the + * private use blocks in the Unicode standard. This class extends + * UnassignedCharacters because the return type from getType() is + * different. + * @author Anthony Balkissoon abalkiss at redhat dot com + * + */ + private static class PrivateUseCharacters extends UnassignedCharacters + { + /** + * Returns the type of the character cp. + */ + static int getType(int cp) + { + // The upper 2 code points in any plane are considered unassigned, + // even in the private-use planes. + if ((cp & 0xffff) >= 0xfffe) + return UnassignedCharacters.getType(cp); + return PRIVATE_USE; + } + + /** + * Returns true if the character cp is defined. + */ + static boolean isDefined(int cp) + { + // The upper 2 code points in any plane are considered unassigned, + // even in the private-use planes. + if ((cp & 0xffff) >= 0xfffe) + return UnassignedCharacters.isDefined(cp); + return true; + } + + /** + * Gets the directionality for the character cp. + */ + static byte getDirectionality(int cp) + { + if ((cp & 0xffff) >= 0xfffe) + return UnassignedCharacters.getDirectionality(cp); + return DIRECTIONALITY_LEFT_TO_RIGHT; + } + } + + /** + * A class to encompass all the properties of code points that are + * currently undefined in the Unicode standard. + * @author Anthony Balkissoon abalkiss at redhat dot com + * + */ + private static class UnassignedCharacters + { + /** + * Returns the numeric value for the unassigned characters. + * @param cp the character + * @param radix the radix (not used) + * @return the numeric value of this character in this radix + */ + static int digit(int cp, int radix) + { + return -1; + } + + /** + * Returns the Unicode directionality property for unassigned + * characters. + * @param cp the character + * @return DIRECTIONALITY_UNDEFINED + */ + static byte getDirectionality(int cp) + { + return DIRECTIONALITY_UNDEFINED; + } + + /** + * Returns -1, the numeric value for unassigned Unicode characters. + * @param cp the character + * @return -1 + */ + static int getNumericValue(int cp) + { + return -1; + } + + /** + * Returns UNASSIGNED, the type of unassigned Unicode characters. + * @param cp the character + * @return UNASSIGNED + */ + static int getType(int cp) + { + return UNASSIGNED; + } + + /** + * Returns false to indiciate that the character is not defined in the + * Unicode standard. + * @param cp the character + * @return false + */ + static boolean isDefined(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character is not a digit. + * @param cp the character + * @return false + */ + static boolean isDigit(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot be ignored + * within an identifier + * @param cp the character + * @return false + */ + static boolean isIdentifierIgnorable(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot be part of a + * Java identifier. + * @param cp the character + * @return false + */ + static boolean isJavaIdentifierPart(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot be start a + * Java identifier. + * @param cp the character + * @return false + */ + static boolean isJavaIdentiferStart(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character is not a letter. + * @param cp the character + * @return false + */ + static boolean isLetter(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot is neither a letter + * nor a digit. + * @param cp the character + * @return false + */ + static boolean isLetterOrDigit(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character is not a lowercase letter. + * @param cp the character + * @return false + */ + static boolean isLowerCase(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot is not mirrored. + * @param cp the character + * @return false + */ + static boolean isMirrored(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character is not a space character. + * @param cp the character + * @return false + */ + static boolean isSpaceChar(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character it not a titlecase letter. + * @param cp the character + * @return false + */ + static boolean isTitleCase(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot be part of a + * Unicode identifier. + * @param cp the character + * @return false + */ + static boolean isUnicodeIdentifierPart(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character cannot start a + * Unicode identifier. + * @param cp the character + * @return false + */ + static boolean isUnicodeIdentifierStart(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character is not an uppercase letter. + * @param cp the character + * @return false + */ + static boolean isUpperCase(int cp) + { + return false; + } + + /** + * Returns false to indicate that the character is not a whitespace + * character. + * @param cp the character + * @return false + */ + static boolean isWhiteSpace(int cp) + { + return false; + } + + /** + * Returns cp to indicate this character has no lowercase conversion. + * @param cp the character + * @return cp + */ + static int toLowerCase(int cp) + { + return cp; + } + + /** + * Returns cp to indicate this character has no titlecase conversion. + * @param cp the character + * @return cp + */ + static int toTitleCase(int cp) + { + return cp; + } + + /** + * Returns cp to indicate this character has no uppercase conversion. + * @param cp the character + * @return cp + */ + static int toUpperCase(int cp) + { + return cp; + } + } + + /** * The immutable value of this Character. * * @serial the value of this Character @@ -1399,39 +2351,128 @@ public final class Character implements Serializable, Comparable /** * Stores unicode block offset lookup table. Exploit package visibility of * String.value to avoid copying the array. - * @see #readChar(char) + * @see #readCodePoint(int) * @see CharData#BLOCKS */ - private static final char[] blocks = String.zeroBasedStringValue(CharData.BLOCKS); + private static final char[][] blocks = + new char[][]{ + String.zeroBasedStringValue(CharData.BLOCKS[0]), + String.zeroBasedStringValue(CharData.BLOCKS[1]), + String.zeroBasedStringValue(CharData.BLOCKS[2]), + String.zeroBasedStringValue(CharData.BLOCKS[3]), + String.zeroBasedStringValue(CharData.BLOCKS[4]), + String.zeroBasedStringValue(CharData.BLOCKS[5]), + String.zeroBasedStringValue(CharData.BLOCKS[6]), + String.zeroBasedStringValue(CharData.BLOCKS[7]), + String.zeroBasedStringValue(CharData.BLOCKS[8]), + String.zeroBasedStringValue(CharData.BLOCKS[9]), + String.zeroBasedStringValue(CharData.BLOCKS[10]), + String.zeroBasedStringValue(CharData.BLOCKS[11]), + String.zeroBasedStringValue(CharData.BLOCKS[12]), + String.zeroBasedStringValue(CharData.BLOCKS[13]), + String.zeroBasedStringValue(CharData.BLOCKS[14]), + String.zeroBasedStringValue(CharData.BLOCKS[15]), + String.zeroBasedStringValue(CharData.BLOCKS[16])}; /** * Stores unicode attribute offset lookup table. Exploit package visibility * of String.value to avoid copying the array. * @see CharData#DATA - */ - private static final char[] data = String.zeroBasedStringValue(CharData.DATA); + */ + private static final char[][] data = + new char[][]{ + String.zeroBasedStringValue(CharData.DATA[0]), + String.zeroBasedStringValue(CharData.DATA[1]), + String.zeroBasedStringValue(CharData.DATA[2]), + String.zeroBasedStringValue(CharData.DATA[3]), + String.zeroBasedStringValue(CharData.DATA[4]), + String.zeroBasedStringValue(CharData.DATA[5]), + String.zeroBasedStringValue(CharData.DATA[6]), + String.zeroBasedStringValue(CharData.DATA[7]), + String.zeroBasedStringValue(CharData.DATA[8]), + String.zeroBasedStringValue(CharData.DATA[9]), + String.zeroBasedStringValue(CharData.DATA[10]), + String.zeroBasedStringValue(CharData.DATA[11]), + String.zeroBasedStringValue(CharData.DATA[12]), + String.zeroBasedStringValue(CharData.DATA[13]), + String.zeroBasedStringValue(CharData.DATA[14]), + String.zeroBasedStringValue(CharData.DATA[15]), + String.zeroBasedStringValue(CharData.DATA[16])}; /** * Stores unicode numeric value attribute table. Exploit package visibility * of String.value to avoid copying the array. * @see CharData#NUM_VALUE */ - private static final char[] numValue - = String.zeroBasedStringValue(CharData.NUM_VALUE); + private static final char[][] numValue = + new char[][]{ + String.zeroBasedStringValue(CharData.NUM_VALUE[0]), + String.zeroBasedStringValue(CharData.NUM_VALUE[1]), + String.zeroBasedStringValue(CharData.NUM_VALUE[2]), + String.zeroBasedStringValue(CharData.NUM_VALUE[3]), + String.zeroBasedStringValue(CharData.NUM_VALUE[4]), + String.zeroBasedStringValue(CharData.NUM_VALUE[5]), + String.zeroBasedStringValue(CharData.NUM_VALUE[6]), + String.zeroBasedStringValue(CharData.NUM_VALUE[7]), + String.zeroBasedStringValue(CharData.NUM_VALUE[8]), + String.zeroBasedStringValue(CharData.NUM_VALUE[9]), + String.zeroBasedStringValue(CharData.NUM_VALUE[10]), + String.zeroBasedStringValue(CharData.NUM_VALUE[11]), + String.zeroBasedStringValue(CharData.NUM_VALUE[12]), + String.zeroBasedStringValue(CharData.NUM_VALUE[13]), + String.zeroBasedStringValue(CharData.NUM_VALUE[14]), + String.zeroBasedStringValue(CharData.NUM_VALUE[15]), + String.zeroBasedStringValue(CharData.NUM_VALUE[16])}; /** * Stores unicode uppercase attribute table. Exploit package visibility * of String.value to avoid copying the array. * @see CharData#UPPER - */ - private static final char[] upper = String.zeroBasedStringValue(CharData.UPPER); + */ + private static final char[][] upper = + new char[][]{ + String.zeroBasedStringValue(CharData.UPPER[0]), + String.zeroBasedStringValue(CharData.UPPER[1]), + String.zeroBasedStringValue(CharData.UPPER[2]), + String.zeroBasedStringValue(CharData.UPPER[3]), + String.zeroBasedStringValue(CharData.UPPER[4]), + String.zeroBasedStringValue(CharData.UPPER[5]), + String.zeroBasedStringValue(CharData.UPPER[6]), + String.zeroBasedStringValue(CharData.UPPER[7]), + String.zeroBasedStringValue(CharData.UPPER[8]), + String.zeroBasedStringValue(CharData.UPPER[9]), + String.zeroBasedStringValue(CharData.UPPER[10]), + String.zeroBasedStringValue(CharData.UPPER[11]), + String.zeroBasedStringValue(CharData.UPPER[12]), + String.zeroBasedStringValue(CharData.UPPER[13]), + String.zeroBasedStringValue(CharData.UPPER[14]), + String.zeroBasedStringValue(CharData.UPPER[15]), + String.zeroBasedStringValue(CharData.UPPER[16])}; /** * Stores unicode lowercase attribute table. Exploit package visibility * of String.value to avoid copying the array. * @see CharData#LOWER */ - private static final char[] lower = String.zeroBasedStringValue(CharData.LOWER); + private static final char[][] lower = + new char[][]{ + String.zeroBasedStringValue(CharData.LOWER[0]), + String.zeroBasedStringValue(CharData.LOWER[1]), + String.zeroBasedStringValue(CharData.LOWER[2]), + String.zeroBasedStringValue(CharData.LOWER[3]), + String.zeroBasedStringValue(CharData.LOWER[4]), + String.zeroBasedStringValue(CharData.LOWER[5]), + String.zeroBasedStringValue(CharData.LOWER[6]), + String.zeroBasedStringValue(CharData.LOWER[7]), + String.zeroBasedStringValue(CharData.LOWER[8]), + String.zeroBasedStringValue(CharData.LOWER[9]), + String.zeroBasedStringValue(CharData.LOWER[10]), + String.zeroBasedStringValue(CharData.LOWER[11]), + String.zeroBasedStringValue(CharData.LOWER[12]), + String.zeroBasedStringValue(CharData.LOWER[13]), + String.zeroBasedStringValue(CharData.LOWER[14]), + String.zeroBasedStringValue(CharData.LOWER[15]), + String.zeroBasedStringValue(CharData.LOWER[16])}; /** * Stores unicode direction attribute table. Exploit package visibility @@ -1439,14 +2480,32 @@ public final class Character implements Serializable, Comparable * @see CharData#DIRECTION */ // Package visible for use by String. - static final char[] direction = String.zeroBasedStringValue(CharData.DIRECTION); + static final char[][] direction = + new char[][]{ + String.zeroBasedStringValue(CharData.DIRECTION[0]), + String.zeroBasedStringValue(CharData.DIRECTION[1]), + String.zeroBasedStringValue(CharData.DIRECTION[2]), + String.zeroBasedStringValue(CharData.DIRECTION[3]), + String.zeroBasedStringValue(CharData.DIRECTION[4]), + String.zeroBasedStringValue(CharData.DIRECTION[5]), + String.zeroBasedStringValue(CharData.DIRECTION[6]), + String.zeroBasedStringValue(CharData.DIRECTION[7]), + String.zeroBasedStringValue(CharData.DIRECTION[8]), + String.zeroBasedStringValue(CharData.DIRECTION[9]), + String.zeroBasedStringValue(CharData.DIRECTION[10]), + String.zeroBasedStringValue(CharData.DIRECTION[11]), + String.zeroBasedStringValue(CharData.DIRECTION[12]), + String.zeroBasedStringValue(CharData.DIRECTION[13]), + String.zeroBasedStringValue(CharData.DIRECTION[14]), + String.zeroBasedStringValue(CharData.DIRECTION[15]), + String.zeroBasedStringValue(CharData.DIRECTION[16])}; /** * Stores unicode titlecase table. Exploit package visibility of * String.value to avoid copying the array. * @see CharData#TITLE */ - private static final char[] title = String.zeroBasedStringValue(CharData.TITLE); + private static final char[] title = String.zeroBasedStringValue(CharData.TITLE); /** * Mask for grabbing the type out of the contents of data. @@ -1538,7 +2597,7 @@ public final class Character implements Serializable, Comparable * 5 bits are the character type, the next 2 bits are flags, and the top * 9 bits are the offset into the attribute tables. * - * @param ch the character to look up + * @param codePoint the character to look up * @return the character's attribute offset and type * @see #TYPE_MASK * @see #NO_BREAK_MASK @@ -1546,11 +2605,11 @@ public final class Character implements Serializable, Comparable * @see CharData#DATA * @see CharData#SHIFT */ - // Package visible for use in String. - static char readChar(char ch) + static char readCodePoint(int codePoint) { - // Perform 16-bit addition to find the correct entry in data. - return data[(char) (blocks[ch >> CharData.SHIFT] + ch)]; + int plane = codePoint >>> 16; + char offset = (char) (codePoint & 0xffff); + return data[plane][(char) (blocks[plane][offset >> CharData.SHIFT[plane]] + offset)]; } /** @@ -1623,7 +2682,8 @@ public final class Character implements Serializable, Comparable /** * Determines if a character is a Unicode lowercase letter. For example, - * <code>'a'</code> is lowercase. + * <code>'a'</code> is lowercase. Returns true if getType() returns + * LOWERCASE_LETTER. * <br> * lowercase = [Ll] * @@ -1636,12 +2696,34 @@ public final class Character implements Serializable, Comparable */ public static boolean isLowerCase(char ch) { - return getType(ch) == LOWERCASE_LETTER; + return isLowerCase((int)ch); + } + + /** + * Determines if a character is a Unicode lowercase letter. For example, + * <code>'a'</code> is lowercase. Returns true if getType() returns + * LOWERCASE_LETTER. + * <br> + * lowercase = [Ll] + * + * @param codePoint character to test + * @return true if ch is a Unicode lowercase letter, else false + * @see #isUpperCase(char) + * @see #isTitleCase(char) + * @see #toLowerCase(char) + * @see #getType(char) + * + * @since 1.5 + */ + public static boolean isLowerCase(int codePoint) + { + return getType(codePoint) == LOWERCASE_LETTER; } /** * Determines if a character is a Unicode uppercase letter. For example, - * <code>'A'</code> is uppercase. + * <code>'A'</code> is uppercase. Returns true if getType() returns + * UPPERCASE_LETTER. * <br> * uppercase = [Lu] * @@ -1654,12 +2736,34 @@ public final class Character implements Serializable, Comparable */ public static boolean isUpperCase(char ch) { - return getType(ch) == UPPERCASE_LETTER; + return isUpperCase((int)ch); + } + + /** + * Determines if a character is a Unicode uppercase letter. For example, + * <code>'A'</code> is uppercase. Returns true if getType() returns + * UPPERCASE_LETTER. + * <br> + * uppercase = [Lu] + * + * @param codePoint character to test + * @return true if ch is a Unicode uppercase letter, else false + * @see #isLowerCase(char) + * @see #isTitleCase(char) + * @see #toUpperCase(char) + * @see #getType(char) + * + * @since 1.5 + */ + public static boolean isUpperCase(int codePoint) + { + return getType(codePoint) == UPPERCASE_LETTER; } /** * Determines if a character is a Unicode titlecase letter. For example, * the character "Lj" (Latin capital L with small letter j) is titlecase. + * True if getType() returns TITLECASE_LETTER. * <br> * titlecase = [Lt] * @@ -1672,12 +2776,35 @@ public final class Character implements Serializable, Comparable */ public static boolean isTitleCase(char ch) { - return getType(ch) == TITLECASE_LETTER; + return isTitleCase((int)ch); } + + /** + * Determines if a character is a Unicode titlecase letter. For example, + * the character "Lj" (Latin capital L with small letter j) is titlecase. + * True if getType() returns TITLECASE_LETTER. + * <br> + * titlecase = [Lt] + * + * @param codePoint character to test + * @return true if ch is a Unicode titlecase letter, else false + * @see #isLowerCase(char) + * @see #isUpperCase(char) + * @see #toTitleCase(char) + * @see #getType(char) + * + * @since 1.5 + */ + public static boolean isTitleCase(int codePoint) + { + return getType(codePoint) == TITLECASE_LETTER; + } + /** * Determines if a character is a Unicode decimal digit. For example, - * <code>'0'</code> is a digit. + * <code>'0'</code> is a digit. A character is a Unicode digit if + * getType() returns DECIMAL_DIGIT_NUMBER. * <br> * Unicode decimal digit = [Nd] * @@ -1689,7 +2816,28 @@ public final class Character implements Serializable, Comparable */ public static boolean isDigit(char ch) { - return getType(ch) == DECIMAL_DIGIT_NUMBER; + return isDigit((int)ch); + } + + /** + * Determines if a character is a Unicode decimal digit. For example, + * <code>'0'</code> is a digit. A character is a Unicode digit if + * getType() returns DECIMAL_DIGIT_NUMBER. + * <br> + * Unicode decimal digit = [Nd] + * + * @param codePoint character to test + * @return true if ch is a Unicode decimal digit, else false + * @see #digit(char, int) + * @see #forDigit(int, int) + * @see #getType(char) + * + * @since 1.5 + */ + + public static boolean isDigit(int codePoint) + { + return getType(codePoint) == DECIMAL_DIGIT_NUMBER; } /** @@ -1709,12 +2857,37 @@ public final class Character implements Serializable, Comparable */ public static boolean isDefined(char ch) { - return getType(ch) != UNASSIGNED; + return isDefined((int)ch); + } + + /** + * Determines if a character is part of the Unicode Standard. This is an + * evolving standard, but covers every character in the data file. + * <br> + * defined = not [Cn] + * + * @param codePoint character to test + * @return true if ch is a Unicode character, else false + * @see #isDigit(char) + * @see #isLetter(char) + * @see #isLetterOrDigit(char) + * @see #isLowerCase(char) + * @see #isTitleCase(char) + * @see #isUpperCase(char) + * + * @since 1.5 + */ + public static boolean isDefined(int codePoint) + { + return getType(codePoint) != UNASSIGNED; } /** * Determines if a character is a Unicode letter. Not all letters have case, * so this may return true when isLowerCase and isUpperCase return false. + * A character is a Unicode letter if getType() returns one of + * UPPERCASE_LETTER, LOWERCASE_LETTER, TITLECASE_LETTER, MODIFIER_LETTER, + * or OTHER_LETTER. * <br> * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo] * @@ -1732,12 +2905,242 @@ public final class Character implements Serializable, Comparable */ public static boolean isLetter(char ch) { - return ((1 << getType(ch)) - & ((1 << UPPERCASE_LETTER) - | (1 << LOWERCASE_LETTER) - | (1 << TITLECASE_LETTER) - | (1 << MODIFIER_LETTER) - | (1 << OTHER_LETTER))) != 0; + return isLetter((int)ch); + } + + /** + * Determines if a character is a Unicode letter. Not all letters have case, + * so this may return true when isLowerCase and isUpperCase return false. + * A character is a Unicode letter if getType() returns one of + * UPPERCASE_LETTER, LOWERCASE_LETTER, TITLECASE_LETTER, MODIFIER_LETTER, + * or OTHER_LETTER. + * <br> + * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo] + * + * @param codePoint character to test + * @return true if ch is a Unicode letter, else false + * @see #isDigit(char) + * @see #isJavaIdentifierStart(char) + * @see #isJavaLetter(char) + * @see #isJavaLetterOrDigit(char) + * @see #isLetterOrDigit(char) + * @see #isLowerCase(char) + * @see #isTitleCase(char) + * @see #isUnicodeIdentifierStart(char) + * @see #isUpperCase(char) + * + * @since 1.5 + */ + public static boolean isLetter(int codePoint) + { + return ((1 << getType(codePoint)) + & ((1 << UPPERCASE_LETTER) + | (1 << LOWERCASE_LETTER) + | (1 << TITLECASE_LETTER) + | (1 << MODIFIER_LETTER) + | (1 << OTHER_LETTER))) != 0; + } + /** + * Returns the index into the given CharSequence that is offset + * <code>codePointOffset</code> code points from <code>index</code>. + * @param seq the CharSequence + * @param index the start position in the CharSequence + * @param codePointOffset the number of code points offset from the start + * position + * @return the index into the CharSequence that is codePointOffset code + * points offset from index + * + * @throws NullPointerException if seq is null + * @throws IndexOutOfBoundsException if index is negative or greater than the + * length of the sequence. + * @throws IndexOutOfBoundsException if codePointOffset is positive and the + * subsequence from index to the end of seq has fewer than codePointOffset + * code points + * @throws IndexOutOfBoundsException if codePointOffset is negative and the + * subsequence from the start of seq to index has fewer than + * (-codePointOffset) code points + * @since 1.5 + */ + public static int offsetByCodePoints(CharSequence seq, + int index, + int codePointOffset) + { + int len = seq.length(); + if (index < 0 || index > len) + throw new IndexOutOfBoundsException(); + + int numToGo = codePointOffset; + int offset = index; + int adjust = 1; + if (numToGo >= 0) + { + for (; numToGo > 0; offset++) + { + numToGo--; + if (Character.isHighSurrogate(seq.charAt(offset)) + && (offset + 1) < len + && Character.isLowSurrogate(seq.charAt(offset + 1))) + offset++; + } + return offset; + } + else + { + numToGo *= -1; + for (; numToGo > 0;) + { + numToGo--; + offset--; + if (Character.isLowSurrogate(seq.charAt(offset)) + && (offset - 1) >= 0 + && Character.isHighSurrogate(seq.charAt(offset - 1))) + offset--; + } + return offset; + } + } + + /** + * Returns the index into the given char subarray that is offset + * <code>codePointOffset</code> code points from <code>index</code>. + * @param a the char array + * @param start the start index of the subarray + * @param count the length of the subarray + * @param index the index to be offset + * @param codePointOffset the number of code points offset from <code>index + * </code> + * @return the index into the char array + * + * @throws NullPointerException if a is null + * @throws IndexOutOfBoundsException if start or count is negative or if + * start + count is greater than the length of the array + * @throws IndexOutOfBoundsException if index is less than start or larger + * than start + count + * @throws IndexOutOfBoundsException if codePointOffset is positive and the + * subarray from index to start + count - 1 has fewer than codePointOffset + * code points. + * @throws IndexOutOfBoundsException if codePointOffset is negative and the + * subarray from start to index - 1 has fewer than (-codePointOffset) code + * points + * + * @since 1.5 + */ + public static int offsetByCodePoints(char[] a, + int start, + int count, + int index, + int codePointOffset) + { + int len = a.length; + int end = start + count; + if (start < 0 || count < 0 || end > len || index < start || index > end) + throw new IndexOutOfBoundsException(); + + int numToGo = codePointOffset; + int offset = index; + int adjust = 1; + if (numToGo >= 0) + { + for (; numToGo > 0; offset++) + { + numToGo--; + if (Character.isHighSurrogate(a[offset]) + && (offset + 1) < len + && Character.isLowSurrogate(a[offset + 1])) + offset++; + } + return offset; + } + else + { + numToGo *= -1; + for (; numToGo > 0;) + { + numToGo--; + offset--; + if (Character.isLowSurrogate(a[offset]) + && (offset - 1) >= 0 + && Character.isHighSurrogate(a[offset - 1])) + offset--; + if (offset < start) + throw new IndexOutOfBoundsException(); + } + return offset; + } + + } + + /** + * Returns the number of Unicode code points in the specified range of the + * given CharSequence. The first char in the range is at position + * beginIndex and the last one is at position endIndex - 1. Paired + * surrogates (supplementary characters are represented by a pair of chars - + * one from the high surrogates and one from the low surrogates) + * count as just one code point. + * @param seq the CharSequence to inspect + * @param beginIndex the beginning of the range + * @param endIndex the end of the range + * @return the number of Unicode code points in the given range of the + * sequence + * @throws NullPointerException if seq is null + * @throws IndexOutOfBoundsException if beginIndex is negative, endIndex is + * larger than the length of seq, or if beginIndex is greater than endIndex. + * @since 1.5 + */ + public static int codePointCount(CharSequence seq, int beginIndex, + int endIndex) + { + int len = seq.length(); + if (beginIndex < 0 || endIndex > len || beginIndex > endIndex) + throw new IndexOutOfBoundsException(); + + int count = 0; + for (int i = beginIndex; i < endIndex; i++) + { + count++; + // If there is a pairing, count it only once. + if (isHighSurrogate(seq.charAt(i)) && (i + 1) < endIndex + && isLowSurrogate(seq.charAt(i + 1))) + i ++; + } + return count; + } + + /** + * Returns the number of Unicode code points in the specified range of the + * given char array. The first char in the range is at position + * offset and the length of the range is count. Paired surrogates + * (supplementary characters are represented by a pair of chars - + * one from the high surrogates and one from the low surrogates) + * count as just one code point. + * @param a the char array to inspect + * @param offset the beginning of the range + * @param count the length of the range + * @return the number of Unicode code points in the given range of the + * array + * @throws NullPointerException if a is null + * @throws IndexOutOfBoundsException if offset or count is negative or if + * offset + countendIndex is larger than the length of a. + * @since 1.5 + */ + public static int codePointCount(char[] a, int offset, + int count) + { + int len = a.length; + int end = offset + count; + if (offset < 0 || count < 0 || end > len) + throw new IndexOutOfBoundsException(); + + int counter = 0; + for (int i = offset; i < end; i++) + { + counter++; + // If there is a pairing, count it only once. + if (isHighSurrogate(a[i]) && (i + 1) < end + && isLowSurrogate(a[i + 1])) + i ++; + } + return counter; } /** @@ -1757,16 +3160,38 @@ public final class Character implements Serializable, Comparable */ public static boolean isLetterOrDigit(char ch) { - return ((1 << getType(ch)) - & ((1 << UPPERCASE_LETTER) - | (1 << LOWERCASE_LETTER) - | (1 << TITLECASE_LETTER) - | (1 << MODIFIER_LETTER) - | (1 << OTHER_LETTER) - | (1 << DECIMAL_DIGIT_NUMBER))) != 0; + return isLetterOrDigit((int)ch); } /** + * Determines if a character is a Unicode letter or a Unicode digit. This + * is the combination of isLetter and isDigit. + * <br> + * letter or digit = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nd] + * + * @param codePoint character to test + * @return true if ch is a Unicode letter or a Unicode digit, else false + * @see #isDigit(char) + * @see #isJavaIdentifierPart(char) + * @see #isJavaLetter(char) + * @see #isJavaLetterOrDigit(char) + * @see #isLetter(char) + * @see #isUnicodeIdentifierPart(char) + * + * @since 1.5 + */ + public static boolean isLetterOrDigit(int codePoint) + { + return ((1 << getType(codePoint)) + & ((1 << UPPERCASE_LETTER) + | (1 << LOWERCASE_LETTER) + | (1 << TITLECASE_LETTER) + | (1 << MODIFIER_LETTER) + | (1 << OTHER_LETTER) + | (1 << DECIMAL_DIGIT_NUMBER))) != 0; + } + + /** * Determines if a character can start a Java identifier. This is the * combination of isLetter, any character where getType returns * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation @@ -1827,7 +3252,27 @@ public final class Character implements Serializable, Comparable */ public static boolean isJavaIdentifierStart(char ch) { - return ((1 << getType(ch)) + return isJavaIdentifierStart((int)ch); + } + + /** + * Determines if a character can start a Java identifier. This is the + * combination of isLetter, any character where getType returns + * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation + * (like '_'). + * <br> + * Java identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc] + * + * @param codePoint character to test + * @return true if ch can start a Java identifier, else false + * @see #isJavaIdentifierPart(char) + * @see #isLetter(char) + * @see #isUnicodeIdentifierStart(char) + * @since 1.5 + */ + public static boolean isJavaIdentifierStart(int codePoint) + { + return ((1 << getType(codePoint)) & ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) | (1 << TITLECASE_LETTER) @@ -1837,7 +3282,7 @@ public final class Character implements Serializable, Comparable | (1 << CURRENCY_SYMBOL) | (1 << CONNECTOR_PUNCTUATION))) != 0; } - + /** * Determines if a character can follow the first letter in * a Java identifier. This is the combination of isJavaLetter (isLetter, @@ -1859,7 +3304,31 @@ public final class Character implements Serializable, Comparable */ public static boolean isJavaIdentifierPart(char ch) { - int category = getType(ch); + return isJavaIdentifierPart((int)ch); + } + + /** + * Determines if a character can follow the first letter in + * a Java identifier. This is the combination of isJavaLetter (isLetter, + * type of LETTER_NUMBER, currency, connecting punctuation) and digit, + * numeric letter (like Roman numerals), combining marks, non-spacing marks, + * or isIdentifierIgnorable. + * <br> + * Java identifier extender = + * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]|[Mn]|[Mc]|[Nd]|[Cf] + * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F + * + * @param codePoint character to test + * @return true if ch can follow the first letter in a Java identifier + * @see #isIdentifierIgnorable(char) + * @see #isJavaIdentifierStart(char) + * @see #isLetterOrDigit(char) + * @see #isUnicodeIdentifierPart(char) + * @since 1.5 + */ + public static boolean isJavaIdentifierPart(int codePoint) + { + int category = getType(codePoint); return ((1 << category) & ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) @@ -1873,7 +3342,7 @@ public final class Character implements Serializable, Comparable | (1 << CURRENCY_SYMBOL) | (1 << CONNECTOR_PUNCTUATION) | (1 << FORMAT))) != 0 - || (category == CONTROL && isIdentifierIgnorable(ch)); + || (category == CONTROL && isIdentifierIgnorable(codePoint)); } /** @@ -1892,7 +3361,26 @@ public final class Character implements Serializable, Comparable */ public static boolean isUnicodeIdentifierStart(char ch) { - return ((1 << getType(ch)) + return isUnicodeIdentifierStart((int)ch); + } + + /** + * Determines if a character can start a Unicode identifier. Only + * letters can start a Unicode identifier, but this includes characters + * in LETTER_NUMBER. + * <br> + * Unicode identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl] + * + * @param codePoint character to test + * @return true if ch can start a Unicode identifier, else false + * @see #isJavaIdentifierStart(char) + * @see #isLetter(char) + * @see #isUnicodeIdentifierPart(char) + * @since 1.5 + */ + public static boolean isUnicodeIdentifierStart(int codePoint) + { + return ((1 << getType(codePoint)) & ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) | (1 << TITLECASE_LETTER) @@ -1921,7 +3409,30 @@ public final class Character implements Serializable, Comparable */ public static boolean isUnicodeIdentifierPart(char ch) { - int category = getType(ch); + return isUnicodeIdentifierPart((int)ch); + } + + /** + * Determines if a character can follow the first letter in + * a Unicode identifier. This includes letters, connecting punctuation, + * digits, numeric letters, combining marks, non-spacing marks, and + * isIdentifierIgnorable. + * <br> + * Unicode identifier extender = + * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Mn]|[Mc]|[Nd]|[Pc]|[Cf]| + * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F + * + * @param codePoint character to test + * @return true if ch can follow the first letter in a Unicode identifier + * @see #isIdentifierIgnorable(char) + * @see #isJavaIdentifierPart(char) + * @see #isLetterOrDigit(char) + * @see #isUnicodeIdentifierStart(char) + * @since 1.5 + */ + public static boolean isUnicodeIdentifierPart(int codePoint) + { + int category = getType(codePoint); return ((1 << category) & ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) @@ -1934,7 +3445,7 @@ public final class Character implements Serializable, Comparable | (1 << LETTER_NUMBER) | (1 << CONNECTOR_PUNCTUATION) | (1 << FORMAT))) != 0 - || (category == CONTROL && isIdentifierIgnorable(ch)); + || (category == CONTROL && isIdentifierIgnorable(codePoint)); } /** @@ -1955,9 +3466,32 @@ public final class Character implements Serializable, Comparable */ public static boolean isIdentifierIgnorable(char ch) { - return (ch <= '\u009F' && (ch < '\t' || ch >= '\u007F' - || (ch <= '\u001B' && ch >= '\u000E'))) - || getType(ch) == FORMAT; + return isIdentifierIgnorable((int)ch); + } + /** + * Determines if a character is ignorable in a Unicode identifier. This + * includes the non-whitespace ISO control characters (<code>'\u0000'</code> + * through <code>'\u0008'</code>, <code>'\u000E'</code> through + * <code>'\u001B'</code>, and <code>'\u007F'</code> through + * <code>'\u009F'</code>), and FORMAT characters. + * <br> + * Unicode identifier ignorable = [Cf]|U+0000-U+0008|U+000E-U+001B + * |U+007F-U+009F + * + * @param codePoint character to test + * @return true if ch is ignorable in a Unicode or Java identifier + * @see #isJavaIdentifierPart(char) + * @see #isUnicodeIdentifierPart(char) + * @since 1.5 + */ + public static boolean isIdentifierIgnorable(int codePoint) + { + if ((codePoint >= 0 && codePoint <= 0x0008) + || (codePoint >= 0x000E && codePoint <= 0x001B) + || (codePoint >= 0x007F && codePoint <= 0x009F) + || getType(codePoint) == FORMAT) + return true; + return false; } /** @@ -1975,8 +3509,37 @@ public final class Character implements Serializable, Comparable */ public static char toLowerCase(char ch) { - // Signedness doesn't matter, as result is cast back to char. - return (char) (ch + lower[readChar(ch) >> 7]); + return (char) (lower[0][readCodePoint((int)ch) >>> 7] + ch); + } + + /** + * Converts a Unicode character into its lowercase equivalent mapping. + * If a mapping does not exist, then the character passed is returned. + * Note that isLowerCase(toLowerCase(ch)) does not always return true. + * + * @param codePoint character to convert to lowercase + * @return lowercase mapping of ch, or ch if lowercase mapping does + * not exist + * @see #isLowerCase(char) + * @see #isUpperCase(char) + * @see #toTitleCase(char) + * @see #toUpperCase(char) + * + * @since 1.5 + */ + public static int toLowerCase(int codePoint) + { + // If the code point is unassigned or in one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.toLowerCase(codePoint); + if (plane > 14) + return PrivateUseCharacters.toLowerCase(codePoint); + + // The short value stored in lower[plane] is the signed difference between + // codePoint and its lowercase conversion. + return ((short)lower[plane][readCodePoint(codePoint) >>> 7]) + codePoint; } /** @@ -1994,8 +3557,37 @@ public final class Character implements Serializable, Comparable */ public static char toUpperCase(char ch) { - // Signedness doesn't matter, as result is cast back to char. - return (char) (ch + upper[readChar(ch) >> 7]); + return (char) (upper[0][readCodePoint((int)ch) >>> 7] + ch); + } + + /** + * Converts a Unicode character into its uppercase equivalent mapping. + * If a mapping does not exist, then the character passed is returned. + * Note that isUpperCase(toUpperCase(ch)) does not always return true. + * + * @param codePoint character to convert to uppercase + * @return uppercase mapping of ch, or ch if uppercase mapping does + * not exist + * @see #isLowerCase(char) + * @see #isUpperCase(char) + * @see #toLowerCase(char) + * @see #toTitleCase(char) + * + * @since 1.5 + */ + public static int toUpperCase(int codePoint) + { + // If the code point is unassigned or in one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.toUpperCase(codePoint); + if (plane > 14) + return PrivateUseCharacters.toUpperCase(codePoint); + + // The short value stored in upper[plane] is the signed difference between + // codePoint and its uppercase conversion. + return ((short)upper[plane][readCodePoint(codePoint) >>> 7]) + codePoint; } /** @@ -2018,6 +3610,30 @@ public final class Character implements Serializable, Comparable return title[i + 1]; return toUpperCase(ch); } + + /** + * Converts a Unicode character into its titlecase equivalent mapping. + * If a mapping does not exist, then the character passed is returned. + * Note that isTitleCase(toTitleCase(ch)) does not always return true. + * + * @param codePoint character to convert to titlecase + * @return titlecase mapping of ch, or ch if titlecase mapping does + * not exist + * @see #isTitleCase(char) + * @see #toLowerCase(char) + * @see #toUpperCase(char) + * + * @since 1.5 + */ + public static int toTitleCase(int codePoint) + { + // As of Unicode 4.0.0 no characters outside of plane 0 have + // titlecase mappings that are different from their uppercase + // mapping. + if (codePoint < 0x10000) + return (int) toTitleCase((char)codePoint); + return toUpperCase(codePoint); + } /** * Converts a character into a digit of the specified radix. If the radix @@ -2041,20 +3657,68 @@ public final class Character implements Serializable, Comparable { if (radix < MIN_RADIX || radix > MAX_RADIX) return -1; - char attr = readChar(ch); + char attr = readCodePoint((int)ch); if (((1 << (attr & TYPE_MASK)) & ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) | (1 << DECIMAL_DIGIT_NUMBER))) != 0) { // Signedness doesn't matter; 0xffff vs. -1 are both rejected. - int digit = numValue[attr >> 7]; + int digit = numValue[0][attr >> 7]; return (digit < radix) ? digit : -1; } return -1; } /** + * Converts a character into a digit of the specified radix. If the radix + * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(ch) + * exceeds the radix, or if ch is not a decimal digit or in the case + * insensitive set of 'a'-'z', the result is -1. + * <br> + * character argument boundary = [Nd]|U+0041-U+005A|U+0061-U+007A + * |U+FF21-U+FF3A|U+FF41-U+FF5A + * + * @param codePoint character to convert into a digit + * @param radix radix in which ch is a digit + * @return digit which ch represents in radix, or -1 not a valid digit + * @see #MIN_RADIX + * @see #MAX_RADIX + * @see #forDigit(int, int) + * @see #isDigit(char) + * @see #getNumericValue(char) + */ + public static int digit(int codePoint, int radix) + { + if (radix < MIN_RADIX || radix > MAX_RADIX) + return -1; + + // If the code point is unassigned or in one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.digit(codePoint, radix); + if (plane > 14) + return PrivateUseCharacters.digit(codePoint, radix); + char attr = readCodePoint(codePoint); + if (((1 << (attr & TYPE_MASK)) + & ((1 << UPPERCASE_LETTER) + | (1 << LOWERCASE_LETTER) + | (1 << DECIMAL_DIGIT_NUMBER))) != 0) + { + // Signedness doesn't matter; 0xffff vs. -1 are both rejected. + int digit = numValue[plane][attr >> 7]; + + // If digit is less than or equal to -3 then the numerical value was + // too large to fit into numValue and is stored in CharData.LARGENUMS. + if (digit <= -3) + digit = CharData.LARGENUMS[-digit - 3]; + return (digit < radix) ? digit : -1; + } + return -1; + } + + /** * Returns the Unicode numeric value property of a character. For example, * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50. * @@ -2084,7 +3748,53 @@ public final class Character implements Serializable, Comparable public static int getNumericValue(char ch) { // Treat numValue as signed. - return (short) numValue[readChar(ch) >> 7]; + return (short) numValue[0][readCodePoint((int)ch) >> 7]; + } + + /** + * Returns the Unicode numeric value property of a character. For example, + * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50. + * + * <p>This method also returns values for the letters A through Z, (not + * specified by Unicode), in these ranges: <code>'\u0041'</code> + * through <code>'\u005A'</code> (uppercase); <code>'\u0061'</code> + * through <code>'\u007A'</code> (lowercase); and <code>'\uFF21'</code> + * through <code>'\uFF3A'</code>, <code>'\uFF41'</code> through + * <code>'\uFF5A'</code> (full width variants). + * + * <p>If the character lacks a numeric value property, -1 is returned. + * If the character has a numeric value property which is not representable + * as a nonnegative integer, such as a fraction, -2 is returned. + * + * character argument boundary = [Nd]|[Nl]|[No]|U+0041-U+005A|U+0061-U+007A + * |U+FF21-U+FF3A|U+FF41-U+FF5A + * + * @param codePoint character from which the numeric value property will + * be retrieved + * @return the numeric value property of ch, or -1 if it does not exist, or + * -2 if it is not representable as a nonnegative integer + * @see #forDigit(int, int) + * @see #digit(char, int) + * @see #isDigit(char) + * @since 1.5 + */ + public static int getNumericValue(int codePoint) + { + // If the code point is unassigned or in one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.getNumericValue(codePoint); + if (plane > 14) + return PrivateUseCharacters.getNumericValue(codePoint); + + // If the value N found in numValue[plane] is less than or equal to -3 + // then the numeric value was too big to fit into 16 bits and is + // stored in CharData.LARGENUMS at offset (-N - 3). + short num = (short)numValue[plane][readCodePoint(codePoint) >> 7]; + if (num <= -3) + return CharData.LARGENUMS[-num - 3]; + return num; } /** @@ -2124,7 +3834,23 @@ public final class Character implements Serializable, Comparable */ public static boolean isSpaceChar(char ch) { - return ((1 << getType(ch)) + return isSpaceChar((int)ch); + } + + /** + * Determines if a character is a Unicode space character. This includes + * SPACE_SEPARATOR, LINE_SEPARATOR, and PARAGRAPH_SEPARATOR. + * <br> + * Unicode space = [Zs]|[Zp]|[Zl] + * + * @param codePoint character to test + * @return true if ch is a Unicode space, else false + * @see #isWhitespace(char) + * @since 1.5 + */ + public static boolean isSpaceChar(int codePoint) + { + return ((1 << getType(codePoint)) & ((1 << SPACE_SEPARATOR) | (1 << LINE_SEPARATOR) | (1 << PARAGRAPH_SEPARATOR))) != 0; @@ -2149,13 +3875,41 @@ public final class Character implements Serializable, Comparable */ public static boolean isWhitespace(char ch) { - int attr = readChar(ch); + return isWhitespace((int) ch); + } + + /** + * Determines if a character is Java whitespace. This includes Unicode + * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and + * PARAGRAPH_SEPARATOR) except the non-breaking spaces + * (<code>'\u00A0'</code>, <code>'\u2007'</code>, and <code>'\u202F'</code>); + * and these characters: <code>'\u0009'</code>, <code>'\u000A'</code>, + * <code>'\u000B'</code>, <code>'\u000C'</code>, <code>'\u000D'</code>, + * <code>'\u001C'</code>, <code>'\u001D'</code>, <code>'\u001E'</code>, + * and <code>'\u001F'</code>. + * <br> + * Java whitespace = ([Zs] not Nb)|[Zl]|[Zp]|U+0009-U+000D|U+001C-U+001F + * + * @param codePoint character to test + * @return true if ch is Java whitespace, else false + * @see #isSpaceChar(char) + * @since 1.5 + */ + public static boolean isWhitespace(int codePoint) + { + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.isWhiteSpace(codePoint); + if (plane > 14) + return PrivateUseCharacters.isWhiteSpace(codePoint); + + int attr = readCodePoint(codePoint); return ((((1 << (attr & TYPE_MASK)) & ((1 << SPACE_SEPARATOR) | (1 << LINE_SEPARATOR) | (1 << PARAGRAPH_SEPARATOR))) != 0) && (attr & NO_BREAK_MASK) == 0) - || (ch <= '\u001F' && ((1 << ch) + || (codePoint <= '\u001F' && ((1 << codePoint) & ((1 << '\t') | (1 << '\n') | (1 << '\u000B') @@ -2180,7 +3934,24 @@ public final class Character implements Serializable, Comparable */ public static boolean isISOControl(char ch) { - return getType(ch) == CONTROL; + return isISOControl((int)ch); + } + + /** + * Determines if the character is an ISO Control character. This is true + * if the code point is in the range [0, 0x001F] or if it is in the range + * [0x007F, 0x009F]. + * @param codePoint the character to check + * @return true if the character is in one of the above ranges + * + * @since 1.5 + */ + public static boolean isISOControl(int codePoint) + { + if ((codePoint >= 0 && codePoint <= 0x001F) + || (codePoint >= 0x007F && codePoint <= 0x009F)) + return true; + return false; } /** @@ -2222,7 +3993,58 @@ public final class Character implements Serializable, Comparable */ public static int getType(char ch) { - return readChar(ch) & TYPE_MASK; + return getType((int)ch); + } + + /** + * Returns the Unicode general category property of a character. + * + * @param codePoint character from which the general category property will + * be retrieved + * @return the character category property of ch as an integer + * @see #UNASSIGNED + * @see #UPPERCASE_LETTER + * @see #LOWERCASE_LETTER + * @see #TITLECASE_LETTER + * @see #MODIFIER_LETTER + * @see #OTHER_LETTER + * @see #NON_SPACING_MARK + * @see #ENCLOSING_MARK + * @see #COMBINING_SPACING_MARK + * @see #DECIMAL_DIGIT_NUMBER + * @see #LETTER_NUMBER + * @see #OTHER_NUMBER + * @see #SPACE_SEPARATOR + * @see #LINE_SEPARATOR + * @see #PARAGRAPH_SEPARATOR + * @see #CONTROL + * @see #FORMAT + * @see #PRIVATE_USE + * @see #SURROGATE + * @see #DASH_PUNCTUATION + * @see #START_PUNCTUATION + * @see #END_PUNCTUATION + * @see #CONNECTOR_PUNCTUATION + * @see #OTHER_PUNCTUATION + * @see #MATH_SYMBOL + * @see #CURRENCY_SYMBOL + * @see #MODIFIER_SYMBOL + * @see #INITIAL_QUOTE_PUNCTUATION + * @see #FINAL_QUOTE_PUNCTUATION + * + * @since 1.5 + */ + public static int getType(int codePoint) + { + // If the codePoint is unassigned or in one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.getType(codePoint); + if (plane > 14) + return PrivateUseCharacters.getType(codePoint); + + return readCodePoint(codePoint) & TYPE_MASK; } /** @@ -2279,9 +4101,51 @@ public final class Character implements Serializable, Comparable public static byte getDirectionality(char ch) { // The result will correctly be signed. - return (byte) (direction[readChar(ch) >> 7] >> 2); + return getDirectionality((int)ch); } - + + /** + * Returns the Unicode directionality property of the character. This + * is used in the visual ordering of text. + * + * @param codePoint the character to look up + * @return the directionality constant, or DIRECTIONALITY_UNDEFINED + * @see #DIRECTIONALITY_UNDEFINED + * @see #DIRECTIONALITY_LEFT_TO_RIGHT + * @see #DIRECTIONALITY_RIGHT_TO_LEFT + * @see #DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC + * @see #DIRECTIONALITY_EUROPEAN_NUMBER + * @see #DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR + * @see #DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR + * @see #DIRECTIONALITY_ARABIC_NUMBER + * @see #DIRECTIONALITY_COMMON_NUMBER_SEPARATOR + * @see #DIRECTIONALITY_NONSPACING_MARK + * @see #DIRECTIONALITY_BOUNDARY_NEUTRAL + * @see #DIRECTIONALITY_PARAGRAPH_SEPARATOR + * @see #DIRECTIONALITY_SEGMENT_SEPARATOR + * @see #DIRECTIONALITY_WHITESPACE + * @see #DIRECTIONALITY_OTHER_NEUTRALS + * @see #DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING + * @see #DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE + * @see #DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING + * @see #DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE + * @see #DIRECTIONALITY_POP_DIRECTIONAL_FORMAT + * @since 1.5 + */ + public static byte getDirectionality(int codePoint) + { + // If the code point is unassigned or in one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.getDirectionality(codePoint); + if (plane > 14) + return PrivateUseCharacters.getDirectionality(codePoint); + + // The result will correctly be signed. + return (byte) (direction[plane][readCodePoint(codePoint) >> 7] >> 2); + } + /** * Determines whether the character is mirrored according to Unicode. For * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in @@ -2293,7 +4157,29 @@ public final class Character implements Serializable, Comparable */ public static boolean isMirrored(char ch) { - return (readChar(ch) & MIRROR_MASK) != 0; + return (readCodePoint((int)ch) & MIRROR_MASK) != 0; + } + + /** + * Determines whether the character is mirrored according to Unicode. For + * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in + * left-to-right text, but ')' in right-to-left text. + * + * @param codePoint the character to look up + * @return true if the character is mirrored + * @since 1.5 + */ + public static boolean isMirrored(int codePoint) + { + // If the code point is unassigned or part of one of the private use areas + // then we delegate the call to the appropriate private static inner class. + int plane = codePoint >>> 16; + if (plane > 2 && plane < 14) + return UnassignedCharacters.isMirrored(codePoint); + if (plane > 14) + return PrivateUseCharacters.isMirrored(codePoint); + + return (readCodePoint(codePoint) & MIRROR_MASK) != 0; } /** @@ -2374,6 +4260,9 @@ public final class Character implements Serializable, Comparable */ public static char[] toChars(int codePoint) { + if (!isValidCodePoint(codePoint)) + throw new IllegalArgumentException("Illegal Unicode code point : " + + codePoint); char[] result = new char[charCount(codePoint)]; int ignore = toChars(codePoint, result, 0); return result; @@ -2591,7 +4480,7 @@ public final class Character implements Serializable, Comparable */ public static int codePointAt(char[] chars, int index, int limit) { - if (index < 0 || index >= limit || limit < 0 || limit >= chars.length) + if (index < 0 || index >= limit || limit < 0 || limit > chars.length) throw new IndexOutOfBoundsException(); char high = chars[index]; if (! isHighSurrogate(high) || ++index >= limit) diff --git a/libjava/classpath/java/lang/ClassNotFoundException.java b/libjava/classpath/java/lang/ClassNotFoundException.java index 6b6ae949dd2..142bc5d0306 100644 --- a/libjava/classpath/java/lang/ClassNotFoundException.java +++ b/libjava/classpath/java/lang/ClassNotFoundException.java @@ -70,7 +70,7 @@ public class ClassNotFoundException extends Exception */ public ClassNotFoundException() { - this(null, null); + this(null); } /** @@ -81,7 +81,8 @@ public class ClassNotFoundException extends Exception */ public ClassNotFoundException(String s) { - this(s, null); + super(s); + ex = null; } /** diff --git a/libjava/classpath/java/lang/Math.java b/libjava/classpath/java/lang/Math.java index 08081e2523a..d7c8aa1c433 100644 --- a/libjava/classpath/java/lang/Math.java +++ b/libjava/classpath/java/lang/Math.java @@ -1,5 +1,5 @@ -/* java.lang.Math -- common mathematical functions, native allowed - Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. +/* java.lang.Math -- common mathematical functions, native allowed (VMMath) + Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -52,26 +52,34 @@ import java.util.Random; * @author Paul Fisher * @author John Keiser * @author Eric Blake (ebb9@email.byu.edu) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.0 */ public final class Math { - /** - * Math is non-instantiable - */ - private Math() - { - } + // FIXME - This is here because we need to load the "javalang" system + // library somewhere late in the bootstrap cycle. We cannot do this + // from VMSystem or VMRuntime since those are used to actually load + // the library. This is mainly here because historically Math was + // late enough in the bootstrap cycle to start using System after it + // was initialized (called from the java.util classes). static { if (Configuration.INIT_LOAD_LIBRARY) { - System.loadLibrary("javalang"); + System.loadLibrary("javalang"); } } /** + * Math is non-instantiable + */ + private Math() + { + } + + /** * A random number generator, initialized on first use. */ private static Random rand; @@ -298,7 +306,10 @@ public final class Math * @param a the angle (in radians) * @return sin(a) */ - public static native double sin(double a); + public static double sin(double a) + { + return VMMath.sin(a); + } /** * The trigonometric function <em>cos</em>. The cosine of NaN or infinity is @@ -307,7 +318,10 @@ public final class Math * @param a the angle (in radians) * @return cos(a) */ - public static native double cos(double a); + public static double cos(double a) + { + return VMMath.cos(a); + } /** * The trigonometric function <em>tan</em>. The tangent of NaN or infinity @@ -317,7 +331,10 @@ public final class Math * @param a the angle (in radians) * @return tan(a) */ - public static native double tan(double a); + public static double tan(double a) + { + return VMMath.tan(a); + } /** * The trigonometric function <em>arcsin</em>. The range of angles returned @@ -328,7 +345,10 @@ public final class Math * @param a the sin to turn back into an angle * @return arcsin(a) */ - public static native double asin(double a); + public static double asin(double a) + { + return VMMath.asin(a); + } /** * The trigonometric function <em>arccos</em>. The range of angles returned @@ -339,7 +359,10 @@ public final class Math * @param a the cos to turn back into an angle * @return arccos(a) */ - public static native double acos(double a); + public static double acos(double a) + { + return VMMath.acos(a); + } /** * The trigonometric function <em>arcsin</em>. The range of angles returned @@ -351,7 +374,10 @@ public final class Math * @return arcsin(a) * @see #atan2(double, double) */ - public static native double atan(double a); + public static double atan(double a) + { + return VMMath.atan(a); + } /** * A special version of the trigonometric function <em>arctan</em>, for @@ -400,7 +426,10 @@ public final class Math * @return <em>theta</em> in the conversion of (x, y) to (r, theta) * @see #atan(double) */ - public static native double atan2(double y, double x); + public static double atan2(double y, double x) + { + return VMMath.atan2(y,x); + } /** * Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the @@ -414,7 +443,10 @@ public final class Math * @see #log(double) * @see #pow(double, double) */ - public static native double exp(double a); + public static double exp(double a) + { + return VMMath.exp(a); + } /** * Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the @@ -430,7 +462,10 @@ public final class Math * @return the natural log of <code>a</code> * @see #exp(double) */ - public static native double log(double a); + public static double log(double a) + { + return VMMath.log(a); + } /** * Take a square root. If the argument is NaN or negative, the result is @@ -438,13 +473,18 @@ public final class Math * infinity; and if the result is either zero, the result is the same. * This is accurate within the limits of doubles. * - * <p>For other roots, use pow(a, 1 / rootNumber). + * <p>For a cube root, use <code>cbrt</code>. For other roots, use + * <code>pow(a, 1 / rootNumber)</code>.</p> * * @param a the numeric argument * @return the square root of the argument + * @see #cbrt(double) * @see #pow(double, double) */ - public static native double sqrt(double a); + public static double sqrt(double a) + { + return VMMath.sqrt(a); + } /** * Raise a number to a power. Special cases:<ul> @@ -514,7 +554,10 @@ public final class Math * @param b the power to raise it to * @return a<sup>b</sup> */ - public static native double pow(double a, double b); + public static double pow(double a, double b) + { + return VMMath.pow(a,b); + } /** * Get the IEEE 754 floating point remainder on two numbers. This is the @@ -530,7 +573,10 @@ public final class Math * @return the IEEE 754-defined floating point remainder of x/y * @see #rint(double) */ - public static native double IEEEremainder(double x, double y); + public static double IEEEremainder(double x, double y) + { + return VMMath.IEEEremainder(x,y); + } /** * Take the nearest integer that is that is greater than or equal to the @@ -541,7 +587,10 @@ public final class Math * @param a the value to act upon * @return the nearest integer >= <code>a</code> */ - public static native double ceil(double a); + public static double ceil(double a) + { + return VMMath.ceil(a); + } /** * Take the nearest integer that is that is less than or equal to the @@ -551,7 +600,10 @@ public final class Math * @param a the value to act upon * @return the nearest integer <= <code>a</code> */ - public static native double floor(double a); + public static double floor(double a) + { + return VMMath.floor(a); + } /** * Take the nearest integer to the argument. If it is exactly between @@ -561,7 +613,10 @@ public final class Math * @param a the value to act upon * @return the nearest integer to <code>a</code> */ - public static native double rint(double a); + public static double rint(double a) + { + return VMMath.rint(a); + } /** * Take the nearest integer to the argument. This is equivalent to @@ -647,4 +702,250 @@ public final class Math { return (rads * 180) / PI; } + + /** + * <p> + * Take a cube root. If the argument is <code>NaN</code>, an infinity or + * zero, then the original value is returned. The returned result is + * within 1 ulp of the exact result. For a finite value, <code>x</code>, + * the cube root of <code>-x</code> is equal to the negation of the cube root + * of <code>x</code>. + * </p> + * <p> + * For a square root, use <code>sqrt</code>. For other roots, use + * <code>pow(a, 1 / rootNumber)</code>. + * </p> + * + * @param a the numeric argument + * @return the cube root of the argument + * @see #sqrt(double) + * @see #pow(double, double) + * @since 1.5 + */ + public static double cbrt(double a) + { + return VMMath.cbrt(a); + } + + /** + * <p> + * Returns the hyperbolic cosine of the given value. For a value, + * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> + + * e<sup>-x</sup>)/2</code> + * with <code>e</code> being <a href="#E">Euler's number</a>. The returned + * result is within 2.5 ulps of the exact result. + * </p> + * <p> + * If the supplied value is <code>NaN</code>, then the original value is + * returned. For either infinity, positive infinity is returned. + * The hyperbolic cosine of zero is 1.0. + * </p> + * + * @param a the numeric argument + * @return the hyperbolic cosine of <code>a</code>. + * @since 1.5 + */ + public static double cosh(double a) + { + return VMMath.cosh(a); + } + + /** + * <p> + * Returns <code>e<sup>a</sup> - 1. For values close to 0, the + * result of <code>expm1(a) + 1</code> tend to be much closer to the + * exact result than simply <code>exp(x)</code>. The result is within + * 1 ulp of the exact result, and results are semi-monotonic. For finite + * inputs, the returned value is greater than or equal to -1.0. Once + * a result enters within half a ulp of this limit, the limit is returned. + * </p> + * <p> + * For <code>NaN</code>, positive infinity and zero, the original value + * is returned. Negative infinity returns a result of -1.0 (the limit). + * </p> + * + * @param a the numeric argument + * @return <code>e<sup>a</sup> - 1</code> + * @since 1.5 + */ + public static double expm1(double a) + { + return VMMath.expm1(a); + } + + /** + * <p> + * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>, + * without intermediate overflow or underflow. The returned result is + * within 1 ulp of the exact result. If one parameter is held constant, + * then the result in the other parameter is semi-monotonic. + * </p> + * <p> + * If either of the arguments is an infinity, then the returned result + * is positive infinity. Otherwise, if either argument is <code>NaN</code>, + * then <code>NaN</code> is returned. + * </p> + * + * @param a the first parameter. + * @param b the second parameter. + * @return the hypotenuse matching the supplied parameters. + * @since 1.5 + */ + public static double hypot(double a, double b) + { + return VMMath.hypot(a,b); + } + + /** + * <p> + * Returns the base 10 logarithm of the supplied value. The returned + * result is within 1 ulp of the exact result, and the results are + * semi-monotonic. + * </p> + * <p> + * Arguments of either <code>NaN</code> or less than zero return + * <code>NaN</code>. An argument of positive infinity returns positive + * infinity. Negative infinity is returned if either positive or negative + * zero is supplied. Where the argument is the result of + * <code>10<sup>n</sup</code>, then <code>n</code> is returned. + * </p> + * + * @param a the numeric argument. + * @return the base 10 logarithm of <code>a</code>. + * @since 1.5 + */ + public static double log10(double a) + { + return VMMath.log10(a); + } + + /** + * <p> + * Returns the natural logarithm resulting from the sum of the argument, + * <code>a</code> and 1. For values close to 0, the + * result of <code>log1p(a)</code> tend to be much closer to the + * exact result than simply <code>log(1.0+a)</code>. The returned + * result is within 1 ulp of the exact result, and the results are + * semi-monotonic. + * </p> + * <p> + * Arguments of either <code>NaN</code> or less than -1 return + * <code>NaN</code>. An argument of positive infinity or zero + * returns the original argument. Negative infinity is returned from an + * argument of -1. + * </p> + * + * @param a the numeric argument. + * @return the natural logarithm of <code>a</code> + 1. + * @since 1.5 + */ + public static double log1p(double a) + { + return VMMath.log1p(a); + } + + /** + * <p> + * Returns the sign of the argument as follows: + * </p> + * <ul> + * <li>If <code>a</code> is greater than zero, the result is 1.0.</li> + * <li>If <code>a</code> is less than zero, the result is -1.0.</li> + * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>. + * <li>If <code>a</code> is positive or negative zero, the result is the + * same.</li> + * </ul> + * + * @param a the numeric argument. + * @return the sign of the argument. + * @since 1.5. + */ + public static double signum(double a) + { + if (Double.isNaN(a)) + return Double.NaN; + if (a > 0) + return 1.0; + if (a < 0) + return -1.0; + return a; + } + + /** + * <p> + * Returns the sign of the argument as follows: + * </p> + * <ul> + * <li>If <code>a</code> is greater than zero, the result is 1.0f.</li> + * <li>If <code>a</code> is less than zero, the result is -1.0f.</li> + * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>. + * <li>If <code>a</code> is positive or negative zero, the result is the + * same.</li> + * </ul> + * + * @param a the numeric argument. + * @return the sign of the argument. + * @since 1.5. + */ + public static float signum(float a) + { + if (Float.isNaN(a)) + return Float.NaN; + if (a > 0) + return 1.0f; + if (a < 0) + return -1.0f; + return a; + } + + /** + * <p> + * Returns the hyperbolic sine of the given value. For a value, + * <code>x</code>, the hyperbolic sine is <code>(e<sup>x</sup> - + * e<sup>-x</sup>)/2</code> + * with <code>e</code> being <a href="#E">Euler's number</a>. The returned + * result is within 2.5 ulps of the exact result. + * </p> + * <p> + * If the supplied value is <code>NaN</code>, an infinity or a zero, then the + * original value is returned. + * </p> + * + * @param a the numeric argument + * @return the hyperbolic sine of <code>a</code>. + * @since 1.5 + */ + public static double sinh(double a) + { + return VMMath.sinh(a); + } + + /** + * <p> + * Returns the hyperbolic tangent of the given value. For a value, + * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> - + * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code> + * (i.e. <code>sinh(a)/cosh(a)</code>) + * with <code>e</code> being <a href="#E">Euler's number</a>. The returned + * result is within 2.5 ulps of the exact result. The absolute value + * of the exact result is always less than 1. Computed results are thus + * less than or equal to 1 for finite arguments, with results within + * half a ulp of either positive or negative 1 returning the appropriate + * limit value (i.e. as if the argument was an infinity). + * </p> + * <p> + * If the supplied value is <code>NaN</code> or zero, then the original + * value is returned. Positive infinity returns +1.0 and negative infinity + * returns -1.0. + * </p> + * + * @param a the numeric argument + * @return the hyperbolic tangent of <code>a</code>. + * @since 1.5 + */ + public static double tanh(double a) + { + return VMMath.tanh(a); + } + } diff --git a/libjava/classpath/java/lang/String.java b/libjava/classpath/java/lang/String.java index 231afc77b92..199dfba3545 100644 --- a/libjava/classpath/java/lang/String.java +++ b/libjava/classpath/java/lang/String.java @@ -555,6 +555,49 @@ public final class String implements Serializable, Comparable, CharSequence } /** + * Creates a new String containing the characters represented in the + * given subarray of Unicode code points. + * @param codePoints the entire array of code points + * @param offset the start of the subarray + * @param count the length of the subarray + * + * @throws IllegalArgumentException if an invalid code point is found + * in the codePoints array + * @throws IndexOutOfBoundsException if offset is negative or offset + count + * is greater than the length of the array. + */ + public String(int[] codePoints, int offset, int count) + { + // FIXME: This implementation appears to give correct internal + // representation of the String because: + // - length() is correct + // - getting a char[] from toCharArray() and testing + // Character.codePointAt() on all the characters in that array gives + // the appropriate results + // however printing the String gives incorrect results. This may be + // due to printing method errors (such as incorrectly looping through + // the String one char at a time rather than one "character" at a time. + + if (offset < 0) + throw new IndexOutOfBoundsException(); + int end = offset + count; + int pos = 0; + // This creates a char array that is long enough for all of the code + // points to represent supplementary characters. This is more than likely + // a waste of storage, so we use it only temporarily and then copy the + // used portion into the value array. + char[] temp = new char[2 * codePoints.length]; + for (int i = offset; i < end; i++) + { + pos += Character.toChars(codePoints[i], temp, pos); + } + this.count = pos; + this.value = new char[pos]; + System.arraycopy(temp, 0, value, 0, pos); + this.offset = 0; + } + + /** * Returns the number of characters contained in this String. * * @return the length of this String @@ -1822,7 +1865,7 @@ public final class String implements Serializable, Comparable, CharSequence */ private static int upperCaseExpansion(char ch) { - return Character.direction[Character.readChar(ch) >> 7] & 3; + return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3; } /** @@ -1918,4 +1961,29 @@ public final class String implements Serializable, Comparable, CharSequence } return result.toString(); } + + /** + * Return the index into this String that is offset from the given index by + * <code>codePointOffset</code> code points. + * @param index the index at which to start + * @param codePointOffset the number of code points to offset + * @return the index into this String that is <code>codePointOffset</code> + * code points offset from <code>index</code>. + * + * @throws IndexOutOfBoundsException if index is negative or larger than the + * length of this string. + * @throws IndexOutOfBoundsException if codePointOffset is positive and the + * substring starting with index has fewer than codePointOffset code points. + * @throws IndexOutOfBoundsException if codePointOffset is negative and the + * substring ending with index has fewer than (-codePointOffset) code points. + * @since 1.5 + */ + public int offsetByCodePoints(int index, int codePointOffset) + { + if (index < 0 || index > count) + throw new IndexOutOfBoundsException(); + + return Character.offsetByCodePoints(value, offset, count, offset + index, + codePointOffset); + } } diff --git a/libjava/classpath/java/lang/StringBuilder.java b/libjava/classpath/java/lang/StringBuilder.java index 470f1ba9ad5..01a83ca707b 100644 --- a/libjava/classpath/java/lang/StringBuilder.java +++ b/libjava/classpath/java/lang/StringBuilder.java @@ -1006,4 +1006,65 @@ public final class StringBuilder return false; return true; } + + /** + * Get the code point at the specified index. This is like #charAt(int), + * but if the character is the start of a surrogate pair, and the + * following character completes the pair, then the corresponding + * supplementary code point is returned. + * @param index the index of the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public int codePointAt(int index) + { + return Character.codePointAt(value, index, count); + } + + /** + * Get the code point before the specified index. This is like + * #codePointAt(int), but checks the characters at <code>index-1</code> and + * <code>index-2</code> to see if they form a supplementary code point. + * @param index the index just past the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or >= length() + * @since 1.5 + */ + public int codePointBefore(int index) + { + // Character.codePointBefore() doesn't perform this check. We + // could use the CharSequence overload, but this is just as easy. + if (index >= count) + throw new IndexOutOfBoundsException(); + return Character.codePointBefore(value, index, 1); + } + + /** + * Returns the number of Unicode code points in the specified sub sequence. + * Surrogate pairs count as one code point. + * @param beginIndex the start of the subarray + * @param endIndex the index after the last char in the subarray + * @return the number of code points + * @throws IndexOutOfBoundsException if beginIndex is less than zero or + * greater than endIndex or if endIndex is greater than the length of this + * StringBuilder + */ + public int codePointCount(int beginIndex,int endIndex) + { + if (beginIndex < 0 || beginIndex > endIndex || endIndex > count) + throw new IndexOutOfBoundsException("invalid indices: " + beginIndex + + ", " + endIndex); + return Character.codePointCount(value, beginIndex, endIndex - beginIndex); + } + + public void trimToSize() + { + if (count < value.length) + { + char[] newValue = new char[count]; + System.arraycopy(value, 0, newValue, 0, count); + value = newValue; + } + } } diff --git a/libjava/classpath/java/lang/System.java b/libjava/classpath/java/lang/System.java index ea84dba47e2..34bbfddc672 100644 --- a/libjava/classpath/java/lang/System.java +++ b/libjava/classpath/java/lang/System.java @@ -178,6 +178,23 @@ public final class System if (SecurityManager.current != null) SecurityManager.current.checkPermission (new RuntimePermission("setSecurityManager")); + + // java.security.Security's class initialiser loads and parses the + // policy files. If it hasn't been run already it will be run + // during the first permission check. That initialisation will + // fail if a very restrictive security manager is in force, so we + // preload it here. + if (SecurityManager.current == null) + { + try + { + Class.forName("java.security.Security"); + } + catch (ClassNotFoundException e) + { + } + } + SecurityManager.current = sm; } diff --git a/libjava/classpath/java/lang/Thread.java b/libjava/classpath/java/lang/Thread.java index 9afde5bfd03..76df1037bb5 100644 --- a/libjava/classpath/java/lang/Thread.java +++ b/libjava/classpath/java/lang/Thread.java @@ -906,7 +906,7 @@ public class Thread implements Runnable if (sm != null) { sm.checkAccess(this); - if (this != currentThread()) + if (this != currentThread() || !(t instanceof ThreadDeath)) sm.checkPermission(new RuntimePermission("stopThread")); } VMThread vt = vmThread; diff --git a/libjava/classpath/java/lang/reflect/Proxy.java b/libjava/classpath/java/lang/reflect/Proxy.java index 137cb5a48a6..94aa0bbb2a0 100644 --- a/libjava/classpath/java/lang/reflect/Proxy.java +++ b/libjava/classpath/java/lang/reflect/Proxy.java @@ -1,5 +1,5 @@ /* Proxy.java -- build a proxy class that implements reflected interfaces - Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,7 @@ import gnu.java.lang.reflect.TypeSignature; import java.io.Serializable; import java.security.ProtectionDomain; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -732,6 +733,12 @@ public class Proxy implements Serializable int j = methods.length; while (--j >= 0) { + if (isCoreObjectMethod(methods[j])) + { + // In the case of an attempt to redefine a public non-final + // method of Object, we must skip it + continue; + } ProxySignature sig = new ProxySignature(methods[j]); ProxySignature old = (ProxySignature) method_set.put(sig, sig); if (old != null) @@ -752,6 +759,41 @@ public class Proxy implements Serializable } return data; } + + /** + * Checks whether the method is similar to a public non-final method of + * Object or not (i.e. with the same name and parameter types). Note that we + * can't rely, directly or indirectly (via Collection.contains) on + * Method.equals as it would also check the declaring class, what we do not + * want. We only want to check that the given method have the same signature + * as a core method (same name and parameter types) + * + * @param method the method to check + * @return whether the method has the same name and parameter types as + * Object.equals, Object.hashCode or Object.toString + * @see java.lang.Object#equals(Object) + * @see java.lang.Object#hashCode() + * @see java.lang.Object#toString() + */ + private static boolean isCoreObjectMethod(Method method) + { + String methodName = method.getName(); + if (methodName.equals("equals")) + { + return Arrays.equals(method.getParameterTypes(), + new Class[] { Object.class }); + } + if (methodName.equals("hashCode")) + { + return method.getParameterTypes().length == 0; + } + if (methodName.equals("toString")) + { + return method.getParameterTypes().length == 0; + } + return false; + } + } // class ProxyData /** diff --git a/libjava/classpath/java/math/BigDecimal.java b/libjava/classpath/java/math/BigDecimal.java index 693c399874e..94b373b04be 100644 --- a/libjava/classpath/java/math/BigDecimal.java +++ b/libjava/classpath/java/math/BigDecimal.java @@ -365,16 +365,13 @@ public class BigDecimal extends Number implements Comparable // quotients are the same, so compare remainders - // remove trailing zeros - if (thisParts[1].equals (BigInteger.valueOf (0)) == false) - while (thisParts[1].mod (BigInteger.valueOf (10)).equals - (BigInteger.valueOf (0))) - thisParts[1] = thisParts[1].divide (BigInteger.valueOf (10)); - // again... - if (valParts[1].equals(BigInteger.valueOf (0)) == false) - while (valParts[1].mod (BigInteger.valueOf (10)).equals - (BigInteger.valueOf (0))) - valParts[1] = valParts[1].divide (BigInteger.valueOf (10)); + // Add some trailing zeros to the remainder with the smallest scale + if (scale < val.scale) + thisParts[1] = thisParts[1].multiply + (BigInteger.valueOf (10).pow (val.scale - scale)); + else if (scale > val.scale) + valParts[1] = valParts[1].multiply + (BigInteger.valueOf (10).pow (scale - val.scale)); // and compare them return thisParts[1].compareTo (valParts[1]); diff --git a/libjava/classpath/java/math/BigInteger.java b/libjava/classpath/java/math/BigInteger.java index 5a336b87248..86d6924af02 100644 --- a/libjava/classpath/java/math/BigInteger.java +++ b/libjava/classpath/java/math/BigInteger.java @@ -356,9 +356,9 @@ public class BigInteger extends Number implements Comparable public int signum() { - int top = words == null ? ival : words[ival-1]; - if (top == 0 && words == null) + if (ival == 0 && words == null) return 0; + int top = words == null ? ival : words[ival-1]; return top < 0 ? -1 : 1; } @@ -2227,17 +2227,25 @@ public class BigInteger extends Number implements Comparable throws IOException, ClassNotFoundException { s.defaultReadObject(); - words = byteArrayToIntArray(magnitude, signum < 0 ? -1 : 0); - BigInteger result = make(words, words.length); - this.ival = result.ival; - this.words = result.words; + if (magnitude.length == 0 || signum == 0) + { + this.ival = 0; + this.words = null; + } + else + { + words = byteArrayToIntArray(magnitude, signum < 0 ? -1 : 0); + BigInteger result = make(words, words.length); + this.ival = result.ival; + this.words = result.words; + } } private void writeObject(ObjectOutputStream s) throws IOException, ClassNotFoundException { signum = signum(); - magnitude = toByteArray(); + magnitude = signum == 0 ? new byte[0] : toByteArray(); s.defaultWriteObject(); } } diff --git a/libjava/classpath/java/net/InetAddress.java b/libjava/classpath/java/net/InetAddress.java index 7277331bb26..ce65bc773b5 100644 --- a/libjava/classpath/java/net/InetAddress.java +++ b/libjava/classpath/java/net/InetAddress.java @@ -651,9 +651,9 @@ public class InetAddress implements Serializable /* * Needed for serialization */ - private void readResolve() throws ObjectStreamException + private Object readResolve() throws ObjectStreamException { - // FIXME: implement this + return new Inet4Address(addr, hostName); } private void readObject(ObjectInputStream ois) diff --git a/libjava/classpath/java/net/SocketPermission.java b/libjava/classpath/java/net/SocketPermission.java index 8ccd01baec5..723ccc7a5b5 100644 --- a/libjava/classpath/java/net/SocketPermission.java +++ b/libjava/classpath/java/net/SocketPermission.java @@ -1,5 +1,6 @@ /* SocketPermission.java -- Class modeling permissions for socket operations - Copyright (C) 1998, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1998, 2000, 2001, 2002, 2004, 2006 Free Software + Foundation, Inc. This file is part of GNU Classpath. @@ -37,9 +38,13 @@ exception statement from your version. */ package java.net; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.Serializable; import java.security.Permission; import java.security.PermissionCollection; +import java.util.StringTokenizer; /** @@ -104,25 +109,53 @@ import java.security.PermissionCollection; * * @since 1.2 * - * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Written by Aaron M. Renn (arenn@urbanophile.com) + * @author Extensively modified by Gary Benson (gbenson@redhat.com) */ public final class SocketPermission extends Permission implements Serializable { static final long serialVersionUID = -7204263841984476862L; -// FIXME: Needs serialization work, including readObject/writeObject methods. + /** + * A hostname (possibly wildcarded) or IP address (IPv4 or IPv6). + */ + private transient String host; /** - * A hostname/port combination as described above + * A range of ports. */ - private transient String hostport; + private transient int minport; + private transient int maxport; /** - * A comma separated list of actions for which we have permission + * Values used for minimum and maximum ports when one or both bounds + * are omitted. This class is essentially independent of the + * networking code it describes, so we do not limit ports to the + * usual network limits of 1 and 65535. + */ + private static final int MIN_PORT = 0; + private static final int MAX_PORT = Integer.MAX_VALUE; + + /** + * The actions for which we have permission. This field is present + * to make the serialized form correct and should not be used by + * anything other than writeObject: everything else should use + * actionmask. */ private String actions; /** + * A bitmask representing the actions for which we have permission. + */ + private transient int actionmask; + + /** + * The available actions, in the canonical order required for getActions(). + */ + private static final String[] ACTIONS = new String[] { + "connect", "listen", "accept", "resolve"}; + + /** * Initializes a new instance of <code>SocketPermission</code> with the * specified host/port combination and actions string. * @@ -133,8 +166,137 @@ public final class SocketPermission extends Permission implements Serializable { super(hostport); - this.hostport = hostport; - this.actions = actions; + setHostPort(hostport); + setActions(actions); + } + + /** + * Parse the hostport argument to the constructor. + */ + private void setHostPort(String hostport) + { + // Split into host and ports + String ports; + if (hostport.length() == 0) + { + host = ports = ""; + } + else if (hostport.charAt(0) == '[') + { + // host is a bracketed IPv6 address + int end = hostport.indexOf("]"); + if (end == -1) + throw new IllegalArgumentException("Unmatched '['"); + host = hostport.substring(1, end); + + if (end == hostport.length() - 1) + ports = ""; + else if (hostport.charAt(end + 1) == ':') + ports = hostport.substring(end + 2); + else + throw new IllegalArgumentException("Bad character after ']'"); + } + else + { + // host is a hostname or IPv4 address + int sep = hostport.indexOf(":"); + if (sep == -1) + { + host = hostport; + ports = ""; + } + else + { + host = hostport.substring(0, sep); + ports = hostport.substring(sep + 1); + } + } + if (ports.indexOf(":") != -1) + throw new IllegalArgumentException("Unexpected ':'"); + + // Parse and validate the ports + if (ports.length() == 0) + { + minport = MIN_PORT; + maxport = MAX_PORT; + } + else + { + int sep = ports.indexOf("-"); + if (sep == -1) + { + // a single port + minport = maxport = Integer.parseInt(ports); + } + else + { + if (ports.indexOf("-", sep + 1) != -1) + throw new IllegalArgumentException("Unexpected '-'"); + + if (sep == 0) + { + // an upper bound + minport = MIN_PORT; + maxport = Integer.parseInt(ports.substring(1)); + } + else if (sep == ports.length() - 1) + { + // a lower bound + minport = + Integer.parseInt(ports.substring(0, ports.length() - 1)); + maxport = MAX_PORT; + } + else + { + // a range with two bounds + minport = Integer.parseInt(ports.substring(0, sep)); + maxport = Integer.parseInt(ports.substring(sep + 1)); + } + } + } + } + + /** + * Parse the actions argument to the constructor. + */ + private void setActions(String actionstring) + { + actionmask = 0; + + boolean resolve_needed = false; + boolean resolve_present = false; + + StringTokenizer t = new StringTokenizer(actionstring, ","); + while (t.hasMoreTokens()) + { + String action = t.nextToken(); + action = action.trim().toLowerCase(); + setAction(action); + + if (action.equals("resolve")) + resolve_present = true; + else + resolve_needed = true; + } + + if (resolve_needed && !resolve_present) + setAction("resolve"); + } + + /** + * Parse one element of the actions argument to the constructor. + */ + private void setAction(String action) + { + for (int i = 0; i < ACTIONS.length; i++) + { + if (action.equals(ACTIONS[i])) + { + actionmask |= 1 << i; + return; + } + } + throw new IllegalArgumentException("Unknown action " + action); } /** @@ -150,14 +312,17 @@ public final class SocketPermission extends Permission implements Serializable */ public boolean equals(Object obj) { - if (! (obj instanceof SocketPermission)) - return false; + SocketPermission p; - if (((SocketPermission) obj).hostport.equals(hostport)) - if (((SocketPermission) obj).actions.equals(actions)) - return true; + if (obj instanceof SocketPermission) + p = (SocketPermission) obj; + else + return false; - return false; + return p.actionmask == actionmask && + p.minport == minport && + p.maxport == maxport && + p.host.equals(host); } /** @@ -168,12 +333,7 @@ public final class SocketPermission extends Permission implements Serializable */ public int hashCode() { - int hash = 100; - if (hostport != null) - hash += hostport.hashCode(); - if (actions != null) - hash += actions.hashCode(); - return hash; + return actionmask + minport + maxport + host.hashCode(); } /** @@ -184,38 +344,18 @@ public final class SocketPermission extends Permission implements Serializable */ public String getActions() { - boolean found = false; StringBuffer sb = new StringBuffer(""); - if (actions.indexOf("connect") != -1) + for (int i = 0; i < ACTIONS.length; i++) { - sb.append("connect"); - found = true; + if ((actionmask & (1 << i)) != 0) + { + if (sb.length() != 0) + sb.append(","); + sb.append(ACTIONS[i]); + } } - if (actions.indexOf("listen") != -1) - if (found) - sb.append(",listen"); - else - { - sb.append("listen"); - found = true; - } - - if (actions.indexOf("accept") != -1) - if (found) - sb.append(",accept"); - else - { - sb.append("accept"); - found = true; - } - - if (found) - sb.append(",resolve"); - else if (actions.indexOf("resolve") != -1) - sb.append("resolve"); - return sb.toString(); } @@ -268,136 +408,43 @@ public final class SocketPermission extends Permission implements Serializable return false; // Next check the actions - String ourlist = getActions(); - String theirlist = p.getActions(); + if ((p.actionmask & actionmask) != p.actionmask) + return false; - if (! ourlist.startsWith(theirlist)) + // Then check the ports + if ((p.minport < minport) || (p.maxport > maxport)) return false; - // Now check ports - int ourfirstport = 0; - - // Now check ports - int ourlastport = 0; - - // Now check ports - int theirfirstport = 0; - - // Now check ports - int theirlastport = 0; - - // Get ours - if (hostport.indexOf(":") == -1) - { - ourfirstport = 0; - ourlastport = 65535; - } - else - { - // FIXME: Needs bulletproofing. - // This will dump if hostport if all sorts of bad data was passed to - // the constructor - String range = hostport.substring(hostport.indexOf(":") + 1); - if (range.startsWith("-")) - ourfirstport = 0; - else if (range.indexOf("-") == -1) - ourfirstport = Integer.parseInt(range); - else - ourfirstport = - Integer.parseInt(range.substring(0, range.indexOf("-"))); - - if (range.endsWith("-")) - ourlastport = 65535; - else if (range.indexOf("-") == -1) - ourlastport = Integer.parseInt(range); - else - ourlastport = - Integer.parseInt(range.substring(range.indexOf("-") + 1, - range.length())); - } - - // Get theirs - if (p.hostport.indexOf(":") == -1) - { - theirfirstport = 0; - ourlastport = 65535; - } - else - { - // This will dump if hostport if all sorts of bad data was passed to - // the constructor - String range = p.hostport.substring(hostport.indexOf(":") + 1); - if (range.startsWith("-")) - theirfirstport = 0; - else if (range.indexOf("-") == -1) - theirfirstport = Integer.parseInt(range); - else - theirfirstport = - Integer.parseInt(range.substring(0, range.indexOf("-"))); - - if (range.endsWith("-")) - theirlastport = 65535; - else if (range.indexOf("-") == -1) - theirlastport = Integer.parseInt(range); - else - theirlastport = - Integer.parseInt(range.substring(range.indexOf("-") + 1, - range.length())); - } - - // Now check them - if ((theirfirstport < ourfirstport) || (theirlastport > ourlastport)) - return false; - - // Finally we can check the hosts - String ourhost; - - // Finally we can check the hosts - String theirhost; - - // Get ours - if (hostport.indexOf(":") == -1) - ourhost = hostport; - else - ourhost = hostport.substring(0, hostport.indexOf(":")); - - // Get theirs - if (p.hostport.indexOf(":") == -1) - theirhost = p.hostport; - else - theirhost = p.hostport.substring(0, p.hostport.indexOf(":")); - - // Are they equal? - if (ourhost.equals(theirhost)) + // Finally check the hosts + if (host.equals(p.host)) return true; // Try the canonical names String ourcanonical = null; - - // Try the canonical names String theircanonical = null; try { - ourcanonical = InetAddress.getByName(ourhost).getHostName(); - theircanonical = InetAddress.getByName(theirhost).getHostName(); + ourcanonical = InetAddress.getByName(host).getHostName(); + theircanonical = InetAddress.getByName(p.host).getHostName(); } catch (UnknownHostException e) { // Who didn't resolve? Just assume current address is canonical enough // Is this ok to do? if (ourcanonical == null) - ourcanonical = ourhost; + ourcanonical = host; if (theircanonical == null) - theircanonical = theirhost; + theircanonical = p.host; } if (ourcanonical.equals(theircanonical)) return true; // Well, last chance. Try for a wildcard - if (ourhost.indexOf("*.") != -1) + if (host.indexOf("*.") != -1) { - String wild_domain = ourhost.substring(ourhost.indexOf("*" + 1)); + String wild_domain = + host.substring(host.indexOf("*" + 1)); if (theircanonical.endsWith(wild_domain)) return true; } @@ -405,4 +452,35 @@ public final class SocketPermission extends Permission implements Serializable // Didn't make it return false; } + + /** + * Deserializes a <code>SocketPermission</code> object from + * an input stream. + * + * @param input the input stream. + * @throws IOException if an I/O error occurs in the stream. + * @throws ClassNotFoundException if the class of the + * serialized object could not be found. + */ + private void readObject(ObjectInputStream input) + throws IOException, ClassNotFoundException + { + input.defaultReadObject(); + setHostPort(getName()); + setActions(actions); + } + + /** + * Serializes a <code>SocketPermission</code> object to an + * output stream. + * + * @param output the output stream. + * @throws IOException if an I/O error occurs in the stream. + */ + private void writeObject(ObjectOutputStream output) + throws IOException + { + actions = getActions(); + output.defaultWriteObject(); + } } diff --git a/libjava/classpath/java/net/URI.java b/libjava/classpath/java/net/URI.java index aeceeeec555..39e8dadfc10 100644 --- a/libjava/classpath/java/net/URI.java +++ b/libjava/classpath/java/net/URI.java @@ -1,5 +1,5 @@ /* URI.java -- An URI class - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -346,8 +346,15 @@ public final class URI private static String getURIGroup(Matcher match, int group) { String matched = match.group(group); - return matched.length() == 0 - ? ((match.group(group - 1).length() == 0) ? null : "") : matched; + if (matched == null || matched.length() == 0) + { + String prevMatched = match.group(group -1); + if (prevMatched == null || prevMatched.length() == 0) + return null; + else + return ""; + } + return matched; } /** diff --git a/libjava/classpath/java/net/URL.java b/libjava/classpath/java/net/URL.java index 168c67a19ee..967cc80f69b 100644 --- a/libjava/classpath/java/net/URL.java +++ b/libjava/classpath/java/net/URL.java @@ -399,40 +399,59 @@ public final class URL implements Serializable && ! spec.regionMatches(colon, "://:", 0, 4)) context = null; + boolean protocolSpecified = false; + if ((colon = spec.indexOf(':')) > 0 && (colon < slash || slash < 0)) { - // Protocol specified in spec string. + // Protocol may have been specified in spec string. + protocolSpecified = true; protocol = spec.substring(0, colon).toLowerCase(); - if (context != null && context.protocol.equals(protocol)) - { - // The 1.2 doc specifically says these are copied to the new URL. - host = context.host; - port = context.port; - userInfo = context.userInfo; - authority = context.authority; - } + if (context != null) + { + if (context.protocol.equals(protocol)) + { + // The 1.2 doc specifically says these are copied to the new URL. + host = context.host; + port = context.port; + userInfo = context.userInfo; + authority = context.authority; + } + else + { + // There was a colon in the spec. Check to see if + // what precedes it is a valid protocol. If it was + // not, assume that it is relative to the context. + URLStreamHandler specPh = getURLStreamHandler(protocol.trim()); + if (null == specPh) + protocolSpecified = false; + } + } } - else if (context != null) + + if (!protocolSpecified) { - // Protocol NOT specified in spec string. - // Use context fields (except ref) as a foundation for relative URLs. - colon = -1; - protocol = context.protocol; - host = context.host; - port = context.port; - userInfo = context.userInfo; - if (spec.indexOf(":/", 1) < 0) - { - file = context.file; - if (file == null || file.length() == 0) - file = "/"; - } - authority = context.authority; + if (context != null) + { + // Protocol NOT specified in spec string. + // Use context fields (except ref) as a foundation for relative URLs. + colon = -1; + protocol = context.protocol; + host = context.host; + port = context.port; + userInfo = context.userInfo; + if (spec.indexOf(":/", 1) < 0) + { + file = context.file; + if (file == null || file.length() == 0) + file = "/"; + } + authority = context.authority; + } + else // Protocol NOT specified in spec. and no context available. + throw new MalformedURLException("Absolute URL required with null" + + " context: " + spec); } - else // Protocol NOT specified in spec. and no context available. - throw new MalformedURLException("Absolute URL required with null" - + " context: " + spec); protocol = protocol.trim(); diff --git a/libjava/classpath/java/net/URLClassLoader.java b/libjava/classpath/java/net/URLClassLoader.java index 9d0e5041006..9e489db533f 100644 --- a/libjava/classpath/java/net/URLClassLoader.java +++ b/libjava/classpath/java/net/URLClassLoader.java @@ -1,5 +1,5 @@ /* URLClassLoader.java -- ClassLoader that loads classes from one or more URLs - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -292,9 +292,10 @@ public class URLClassLoader extends SecureClassLoader Vector classPath; // The "Class-Path" attribute of this Jar's manifest - public JarURLLoader(URLClassLoader classloader, URL baseURL) + public JarURLLoader(URLClassLoader classloader, URL baseURL, + URL absoluteUrl) { - super(classloader, baseURL); + super(classloader, baseURL, absoluteUrl); // Cache url prefix for all resources in this jar url. String external = baseURL.toExternalForm(); @@ -526,10 +527,10 @@ public class URLClassLoader extends SecureClassLoader { File dir; //the file for this file url - FileURLLoader(URLClassLoader classloader, URL url) + FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl) { - super(classloader, url); - dir = new File(baseURL.getFile()); + super(classloader, url, absoluteUrl); + dir = new File(absoluteUrl.getFile()); } /** get resource with the name "name" in the file url */ @@ -723,11 +724,42 @@ public class URLClassLoader extends SecureClassLoader String file = newUrl.getFile(); String protocol = newUrl.getProtocol(); + // If we have a file: URL, we want to make it absolute + // here, before we decide whether it is really a jar. + URL absoluteURL; + if ("file".equals (protocol)) + { + File dir = new File(file); + URL absUrl; + try + { + absoluteURL = dir.getCanonicalFile().toURL(); + } + catch (IOException ignore) + { + try + { + absoluteURL = dir.getAbsoluteFile().toURL(); + } + catch (MalformedURLException _) + { + // This really should not happen. + absoluteURL = newUrl; + } + } + } + else + { + // This doesn't hurt, and it simplifies the logic a + // little. + absoluteURL = newUrl; + } + // Check that it is not a directory if (! (file.endsWith("/") || file.endsWith(File.separator))) - loader = new JarURLLoader(this, newUrl); + loader = new JarURLLoader(this, newUrl, absoluteURL); else if ("file".equals(protocol)) - loader = new FileURLLoader(this, newUrl); + loader = new FileURLLoader(this, newUrl, absoluteURL); else loader = new RemoteURLLoader(this, newUrl); diff --git a/libjava/classpath/java/net/URLConnection.java b/libjava/classpath/java/net/URLConnection.java index 836f174dae6..b4a55a01a34 100644 --- a/libjava/classpath/java/net/URLConnection.java +++ b/libjava/classpath/java/net/URLConnection.java @@ -598,6 +598,9 @@ public abstract class URLConnection */ public void setAllowUserInteraction(boolean allow) { + if (connected) + throw new IllegalStateException("Already connected"); + allowUserInteraction = allow; } @@ -776,7 +779,7 @@ public abstract class URLConnection * * @param key The name of the property * - * @return Value of the property + * @return Value of the property, or <code>null</code> if key is null. * * @exception IllegalStateException If already connected * diff --git a/libjava/classpath/java/nio/BufferOverflowException.java b/libjava/classpath/java/nio/BufferOverflowException.java index 588c03290a1..c72ae923801 100644 --- a/libjava/classpath/java/nio/BufferOverflowException.java +++ b/libjava/classpath/java/nio/BufferOverflowException.java @@ -42,6 +42,8 @@ package java.nio; */ public class BufferOverflowException extends RuntimeException { + private static final long serialVersionUID = - 5484897634319144535L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/BufferUnderflowException.java b/libjava/classpath/java/nio/BufferUnderflowException.java index 4b4161c647c..a6d391e00cc 100644 --- a/libjava/classpath/java/nio/BufferUnderflowException.java +++ b/libjava/classpath/java/nio/BufferUnderflowException.java @@ -42,6 +42,8 @@ package java.nio; */ public class BufferUnderflowException extends RuntimeException { + private static final long serialVersionUID = - 1713313658691622206L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/InvalidMarkException.java b/libjava/classpath/java/nio/InvalidMarkException.java index 937d417ab13..013f02f79f2 100644 --- a/libjava/classpath/java/nio/InvalidMarkException.java +++ b/libjava/classpath/java/nio/InvalidMarkException.java @@ -43,6 +43,8 @@ package java.nio; */ public class InvalidMarkException extends IllegalStateException { + private static final long serialVersionUID = 1698329710438510774L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/ReadOnlyBufferException.java b/libjava/classpath/java/nio/ReadOnlyBufferException.java index d710e1b26a1..22f8a6f7379 100644 --- a/libjava/classpath/java/nio/ReadOnlyBufferException.java +++ b/libjava/classpath/java/nio/ReadOnlyBufferException.java @@ -43,6 +43,8 @@ package java.nio; */ public class ReadOnlyBufferException extends UnsupportedOperationException { + private static final long serialVersionUID = - 1210063976496234090L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/AlreadyConnectedException.java b/libjava/classpath/java/nio/channels/AlreadyConnectedException.java index 133547ef308..979486f06c2 100644 --- a/libjava/classpath/java/nio/channels/AlreadyConnectedException.java +++ b/libjava/classpath/java/nio/channels/AlreadyConnectedException.java @@ -39,6 +39,8 @@ package java.nio.channels; public class AlreadyConnectedException extends IllegalStateException { + private static final long serialVersionUID = - 7331895245053773357L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/AsynchronousCloseException.java b/libjava/classpath/java/nio/channels/AsynchronousCloseException.java index f45fdd81ab4..31e41528b1c 100644 --- a/libjava/classpath/java/nio/channels/AsynchronousCloseException.java +++ b/libjava/classpath/java/nio/channels/AsynchronousCloseException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class AsynchronousCloseException extends ClosedChannelException { + private static final long serialVersionUID = 6891178312432313966L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/CancelledKeyException.java b/libjava/classpath/java/nio/channels/CancelledKeyException.java index 02108f6c7b3..d94e6505365 100644 --- a/libjava/classpath/java/nio/channels/CancelledKeyException.java +++ b/libjava/classpath/java/nio/channels/CancelledKeyException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class CancelledKeyException extends IllegalStateException { + private static final long serialVersionUID = - 8438032138028814268L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/Channels.java b/libjava/classpath/java/nio/channels/Channels.java index cdb2e833e9d..cfd8605c3b3 100644 --- a/libjava/classpath/java/nio/channels/Channels.java +++ b/libjava/classpath/java/nio/channels/Channels.java @@ -49,6 +49,7 @@ import java.io.Writer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; +import java.nio.charset.UnsupportedCharsetException; /** diff --git a/libjava/classpath/java/nio/channels/ClosedByInterruptException.java b/libjava/classpath/java/nio/channels/ClosedByInterruptException.java index 17858f613c6..ade7e2a2714 100644 --- a/libjava/classpath/java/nio/channels/ClosedByInterruptException.java +++ b/libjava/classpath/java/nio/channels/ClosedByInterruptException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class ClosedByInterruptException extends AsynchronousCloseException { + private static final long serialVersionUID = - 4488191543534286750L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/ClosedChannelException.java b/libjava/classpath/java/nio/channels/ClosedChannelException.java index 0f8df9b26c4..ea896a0fd4f 100644 --- a/libjava/classpath/java/nio/channels/ClosedChannelException.java +++ b/libjava/classpath/java/nio/channels/ClosedChannelException.java @@ -46,6 +46,8 @@ import java.io.IOException; */ public class ClosedChannelException extends IOException { + private static final long serialVersionUID = 882777185433553857L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/ClosedSelectorException.java b/libjava/classpath/java/nio/channels/ClosedSelectorException.java index e1b7a8ce939..9dfbd7bf84d 100644 --- a/libjava/classpath/java/nio/channels/ClosedSelectorException.java +++ b/libjava/classpath/java/nio/channels/ClosedSelectorException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class ClosedSelectorException extends IllegalStateException { + private static final long serialVersionUID = 6466297122317847835L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/ConnectionPendingException.java b/libjava/classpath/java/nio/channels/ConnectionPendingException.java index b0b71294f7e..2e54ed61a66 100644 --- a/libjava/classpath/java/nio/channels/ConnectionPendingException.java +++ b/libjava/classpath/java/nio/channels/ConnectionPendingException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class ConnectionPendingException extends IllegalStateException { + private static final long serialVersionUID = 2008393366501760879L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/DatagramChannel.java b/libjava/classpath/java/nio/channels/DatagramChannel.java index d257ff33865..b8815f47c28 100644 --- a/libjava/classpath/java/nio/channels/DatagramChannel.java +++ b/libjava/classpath/java/nio/channels/DatagramChannel.java @@ -124,7 +124,6 @@ public abstract class DatagramChannel extends AbstractSelectableChannel /** * Tells whether or not this channel's socket is connected. * - * @exception IOException If an error occurs. * @exception NotYetConnectedException The channel's socket is not connected. */ public abstract boolean isConnected(); @@ -200,7 +199,6 @@ public abstract class DatagramChannel extends AbstractSelectableChannel /** * Retrieves the valid operations for this channel. * - * @exception IOException If an error occurs. * @exception NotYetConnectedException The channel's socket is not connected. */ public final int validOps() diff --git a/libjava/classpath/java/nio/channels/FileChannel.java b/libjava/classpath/java/nio/channels/FileChannel.java index 944ec0b8f3e..0eefffbe97b 100644 --- a/libjava/classpath/java/nio/channels/FileChannel.java +++ b/libjava/classpath/java/nio/channels/FileChannel.java @@ -219,7 +219,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel public abstract void force(boolean metaData) throws IOException; /** - * Creates a file lock for the whole assoziated file. + * Creates a file lock for the whole associated file. * * @exception AsynchronousCloseException If another thread closes this channel * while the transfer is in progress. @@ -242,7 +242,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel } /** - * Creates a file lock for a region of the assoziated file. + * Creates a file lock for a region of the associated file. * * @exception AsynchronousCloseException If another thread closes this channel * while the transfer is in progress. @@ -265,7 +265,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel throws IOException; /** - * Tries to aqquire alock on the whole assoziated file. + * Tries to aqquire alock on the whole associated file. * * @exception ClosedChannelException If this channel is closed. * @exception IOException If an I/O error occurs. @@ -280,7 +280,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel } /** - * Tries to aqquire a lock on a region of the assoziated file. + * Tries to aqquire a lock on a region of the associated file. * * @exception ClosedChannelException If this channel is closed. * @exception IllegalArgumentException If the preconditions on the parameters diff --git a/libjava/classpath/java/nio/channels/FileLockInterruptionException.java b/libjava/classpath/java/nio/channels/FileLockInterruptionException.java index 7d9e620464f..f1024331eea 100644 --- a/libjava/classpath/java/nio/channels/FileLockInterruptionException.java +++ b/libjava/classpath/java/nio/channels/FileLockInterruptionException.java @@ -46,6 +46,8 @@ import java.io.IOException; */ public class FileLockInterruptionException extends IOException { + private static final long serialVersionUID = 7104080643653532383L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/IllegalBlockingModeException.java b/libjava/classpath/java/nio/channels/IllegalBlockingModeException.java index 7352b54f7f1..f34d763824b 100644 --- a/libjava/classpath/java/nio/channels/IllegalBlockingModeException.java +++ b/libjava/classpath/java/nio/channels/IllegalBlockingModeException.java @@ -47,6 +47,8 @@ package java.nio.channels; */ public class IllegalBlockingModeException extends IllegalStateException { + private static final long serialVersionUID = - 3335774961855590474L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/IllegalSelectorException.java b/libjava/classpath/java/nio/channels/IllegalSelectorException.java index 049a8d594f4..01b22529c8a 100644 --- a/libjava/classpath/java/nio/channels/IllegalSelectorException.java +++ b/libjava/classpath/java/nio/channels/IllegalSelectorException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class IllegalSelectorException extends IllegalArgumentException { + private static final long serialVersionUID = - 8406323347253320987L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/NoConnectionPendingException.java b/libjava/classpath/java/nio/channels/NoConnectionPendingException.java index afefebf9807..8dcbdf69559 100644 --- a/libjava/classpath/java/nio/channels/NoConnectionPendingException.java +++ b/libjava/classpath/java/nio/channels/NoConnectionPendingException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class NoConnectionPendingException extends IllegalStateException { + private static final long serialVersionUID = - 8296561183633134743L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/NonReadableChannelException.java b/libjava/classpath/java/nio/channels/NonReadableChannelException.java index e6852a73d3f..bf4f4a4331a 100644 --- a/libjava/classpath/java/nio/channels/NonReadableChannelException.java +++ b/libjava/classpath/java/nio/channels/NonReadableChannelException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class NonReadableChannelException extends IllegalStateException { + private static final long serialVersionUID = - 3200915679294993514L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/NonWritableChannelException.java b/libjava/classpath/java/nio/channels/NonWritableChannelException.java index 61d40bbc4d6..98c86eae291 100644 --- a/libjava/classpath/java/nio/channels/NonWritableChannelException.java +++ b/libjava/classpath/java/nio/channels/NonWritableChannelException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class NonWritableChannelException extends IllegalStateException { + private static final long serialVersionUID = - 7071230488279011621L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/NotYetBoundException.java b/libjava/classpath/java/nio/channels/NotYetBoundException.java index 7d0c66388cd..74bf1ed7f34 100644 --- a/libjava/classpath/java/nio/channels/NotYetBoundException.java +++ b/libjava/classpath/java/nio/channels/NotYetBoundException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class NotYetBoundException extends IllegalStateException { + private static final long serialVersionUID = 4640999303950202242L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/NotYetConnectedException.java b/libjava/classpath/java/nio/channels/NotYetConnectedException.java index 463e05934a8..083ff6c6dcb 100644 --- a/libjava/classpath/java/nio/channels/NotYetConnectedException.java +++ b/libjava/classpath/java/nio/channels/NotYetConnectedException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class NotYetConnectedException extends IllegalStateException { + private static final long serialVersionUID = 4697316551909513464L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/OverlappingFileLockException.java b/libjava/classpath/java/nio/channels/OverlappingFileLockException.java index ce0900c6a49..aa2cedd9a90 100644 --- a/libjava/classpath/java/nio/channels/OverlappingFileLockException.java +++ b/libjava/classpath/java/nio/channels/OverlappingFileLockException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class OverlappingFileLockException extends IllegalStateException { + private static final long serialVersionUID = 2047812138163068433L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/UnresolvedAddressException.java b/libjava/classpath/java/nio/channels/UnresolvedAddressException.java index 4db95a7ffdd..7a591709bf0 100644 --- a/libjava/classpath/java/nio/channels/UnresolvedAddressException.java +++ b/libjava/classpath/java/nio/channels/UnresolvedAddressException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class UnresolvedAddressException extends IllegalArgumentException { + private static final long serialVersionUID = 6136959093620794148L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/UnsupportedAddressTypeException.java b/libjava/classpath/java/nio/channels/UnsupportedAddressTypeException.java index 7c16c813fb0..759d0964cde 100644 --- a/libjava/classpath/java/nio/channels/UnsupportedAddressTypeException.java +++ b/libjava/classpath/java/nio/channels/UnsupportedAddressTypeException.java @@ -44,6 +44,8 @@ package java.nio.channels; */ public class UnsupportedAddressTypeException extends IllegalArgumentException { + private static final long serialVersionUID = - 2964323842829700493L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/channels/spi/AbstractInterruptibleChannel.java b/libjava/classpath/java/nio/channels/spi/AbstractInterruptibleChannel.java index 25e8785c08e..8e5b7b0b158 100644 --- a/libjava/classpath/java/nio/channels/spi/AbstractInterruptibleChannel.java +++ b/libjava/classpath/java/nio/channels/spi/AbstractInterruptibleChannel.java @@ -40,6 +40,7 @@ package java.nio.channels.spi; import java.io.IOException; import java.nio.channels.AsynchronousCloseException; import java.nio.channels.Channel; +import java.nio.channels.ClosedByInterruptException; import java.nio.channels.InterruptibleChannel; @@ -86,7 +87,6 @@ public abstract class AbstractInterruptibleChannel * @param completed true if the task completed successfully, * false otherwise * - * @exception IOException if an error occurs * @exception AsynchronousCloseException If the channel was asynchronously * closed. * @exception ClosedByInterruptException If the thread blocked in the diff --git a/libjava/classpath/java/nio/charset/CharacterCodingException.java b/libjava/classpath/java/nio/charset/CharacterCodingException.java index 6812ebb18a9..d0580c95548 100644 --- a/libjava/classpath/java/nio/charset/CharacterCodingException.java +++ b/libjava/classpath/java/nio/charset/CharacterCodingException.java @@ -44,6 +44,8 @@ import java.io.IOException; */ public class CharacterCodingException extends IOException { + private static final long serialVersionUID = 8421532232154627783L; + /** * Creates the exception */ diff --git a/libjava/classpath/java/nio/charset/CoderMalfunctionError.java b/libjava/classpath/java/nio/charset/CoderMalfunctionError.java index 08294cafb20..5770aded628 100644 --- a/libjava/classpath/java/nio/charset/CoderMalfunctionError.java +++ b/libjava/classpath/java/nio/charset/CoderMalfunctionError.java @@ -42,6 +42,8 @@ package java.nio.charset; */ public class CoderMalfunctionError extends Error { + private static final long serialVersionUID = - 1151412348057794301L; + /** * Creates the error */ diff --git a/libjava/classpath/java/nio/charset/MalformedInputException.java b/libjava/classpath/java/nio/charset/MalformedInputException.java index 0beceb40cb3..463d36868f3 100644 --- a/libjava/classpath/java/nio/charset/MalformedInputException.java +++ b/libjava/classpath/java/nio/charset/MalformedInputException.java @@ -42,6 +42,8 @@ package java.nio.charset; */ public class MalformedInputException extends CharacterCodingException { + private static final long serialVersionUID = - 3438823399834806194L; + private int inputLength; /** diff --git a/libjava/classpath/java/nio/charset/UnmappableCharacterException.java b/libjava/classpath/java/nio/charset/UnmappableCharacterException.java index 71906510849..d22a23807b6 100644 --- a/libjava/classpath/java/nio/charset/UnmappableCharacterException.java +++ b/libjava/classpath/java/nio/charset/UnmappableCharacterException.java @@ -42,6 +42,8 @@ package java.nio.charset; */ public class UnmappableCharacterException extends CharacterCodingException { + private static final long serialVersionUID = - 7026962371537706123L; + private int inputLength; /** diff --git a/libjava/classpath/java/rmi/AccessException.java b/libjava/classpath/java/rmi/AccessException.java index b470780046c..40954dfd3e1 100644 --- a/libjava/classpath/java/rmi/AccessException.java +++ b/libjava/classpath/java/rmi/AccessException.java @@ -1,5 +1,6 @@ /* AccessException.java -- thrown if the caller does not have access - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,7 +44,7 @@ package java.rmi; * * @author unknown * @see Naming - * @see ActivationSystem + * @see java.rmi.activation.ActivationSystem * @since 1.1 */ public class AccessException extends RemoteException diff --git a/libjava/classpath/java/rmi/AlreadyBoundException.java b/libjava/classpath/java/rmi/AlreadyBoundException.java index 091c0ee5862..10f6e4cec98 100644 --- a/libjava/classpath/java/rmi/AlreadyBoundException.java +++ b/libjava/classpath/java/rmi/AlreadyBoundException.java @@ -1,5 +1,6 @@ /* AlreadyBoundException.java -- thrown if a binding is already bound - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,8 +43,8 @@ package java.rmi; * bound. * * @author unknown - * @see Naming#bind(String, Remote) - * @see Registry#bind(String, Remote) + * @see java.rmi.Naming#bind(String, Remote) + * @see java.rmi.registry.Registry#bind(String, Remote) * @since 1.1 * @status updated to 1.4 */ diff --git a/libjava/classpath/java/rmi/MarshalledObject.java b/libjava/classpath/java/rmi/MarshalledObject.java index 9ec0ace0e70..e1a30f5f005 100644 --- a/libjava/classpath/java/rmi/MarshalledObject.java +++ b/libjava/classpath/java/rmi/MarshalledObject.java @@ -1,5 +1,6 @@ /* MarshalledObject.java -- - Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,38 +43,68 @@ import gnu.java.rmi.RMIMarshalledObjectInputStream; import gnu.java.rmi.RMIMarshalledObjectOutputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.Serializable; /** - * FIXME - doc missing + * A <code>MarshalledObject</code> consists of a serialized object which is + * marshalled according to the RMI specification. + * <p> + * An object passed to the constructor is serialized and tagged with the needed + * URL to retrieve its class definition for remote usage. If the object is a + * remote reference its stub is serialized instead. The instance of this + * marshalled object can be later retrieved by its <code>get()</code> method. + * </p> + * + * @author unknown */ -public final class MarshalledObject implements Serializable +public final class MarshalledObject + implements Serializable { - //The following fields are from Java API Documentation "Serialized form" + // The following fields are from Java API Documentation "Serialized form" private static final long serialVersionUID = 8988374069173025854L; + byte[] objBytes; byte[] locBytes; int hash; - - public MarshalledObject(Object obj) throws java.io.IOException + + /** + * Constructs a <code>MarshalledObject</code> from the given object. + * + * @param obj the object to marshal + * @throws IOException if an I/O error during serialization occurs. + */ + public MarshalledObject(Object obj) throws IOException { ByteArrayOutputStream objStream = new ByteArrayOutputStream(); - RMIMarshalledObjectOutputStream stream = new RMIMarshalledObjectOutputStream(objStream); + RMIMarshalledObjectOutputStream stream = + new RMIMarshalledObjectOutputStream(objStream); stream.writeObject(obj); stream.flush(); objBytes = objStream.toByteArray(); locBytes = stream.getLocBytes(); - - //The following algorithm of calculating hashCode is similar to String + + // The following algorithm of calculating hashCode is similar to String hash = 0; for (int i = 0; i < objBytes.length; i++) hash = hash * 31 + objBytes[i]; - if(locBytes != null) + + if (locBytes != null) for (int i = 0; i < locBytes.length; i++) - hash = hash * 31 + locBytes[i]; + hash = hash * 31 + locBytes[i]; } - - public boolean equals(Object obj) + + /** + * Checks if the given object is equal to this marshalled object. + * + * <p>Marshalled objects are considered equal if they contain the + * same serialized object. Codebase annotations where the class + * definition can be downloaded are ignored in the equals test.</p> + * + * @param obj the object to compare. + * @return <code>true</code> if equal, <code>false</code> otherwise. + */ + public boolean equals(Object obj) { if (! (obj instanceof MarshalledObject)) return false; @@ -81,33 +112,43 @@ public final class MarshalledObject implements Serializable // hashCode even differs, don't do the time-consuming comparisons if (obj.hashCode() != hash) return false; - - MarshalledObject aobj = (MarshalledObject)obj; + + MarshalledObject aobj = (MarshalledObject) obj; if (objBytes == null || aobj.objBytes == null) return objBytes == aobj.objBytes; if (objBytes.length != aobj.objBytes.length) return false; - for (int i = 0; i < objBytes.length; i++) + for (int i = 0; i < objBytes.length; i++) { - if (objBytes[i] != aobj.objBytes[i]) - return false; + if (objBytes[i] != aobj.objBytes[i]) + return false; } // Ignore comparison of locBytes(annotation) return true; } - -public Object get() - throws java.io.IOException, java.lang.ClassNotFoundException -{ - if(objBytes == null) - return null; - RMIMarshalledObjectInputStream stream = - new RMIMarshalledObjectInputStream(objBytes, locBytes); - return stream.readObject(); -} - - public int hashCode() { + + /** + * Constructs and returns a copy of the internal serialized object. + * + * @return The deserialized object. + * + * @throws IOException if an I/O exception occurs during deserialization. + * @throws ClassNotFoundException if the class of the deserialized object + * cannot be found. + */ + public Object get() throws IOException, ClassNotFoundException + { + if (objBytes == null) + return null; + + RMIMarshalledObjectInputStream stream = + new RMIMarshalledObjectInputStream(objBytes, locBytes); + return stream.readObject(); + } + + public int hashCode() + { return hash; } - + } diff --git a/libjava/classpath/java/rmi/Naming.java b/libjava/classpath/java/rmi/Naming.java index d48df069d8d..b605da70d12 100644 --- a/libjava/classpath/java/rmi/Naming.java +++ b/libjava/classpath/java/rmi/Naming.java @@ -1,5 +1,6 @@ /* Naming.java -- - Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -76,136 +77,150 @@ import java.rmi.registry.Registry; * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.1 */ -public final class Naming { - +public final class Naming +{ /** * This class isn't intended to be instantiated. */ - private Naming() {} + private Naming() + { + } -/** - * Looks for the remote object that is associated with the named service. - * Name and location is given in form of a URL without a scheme: - * - * <pre> - * //host:port/service-name - * </pre> - * - * The port is optional. - * - * @param name the service name and location - * @return Remote-object that implements the named service - * @throws NotBoundException if no object implements the service - * @throws MalformedURLException - * @throws RemoteException - */ -public static Remote lookup(String name) throws NotBoundException, MalformedURLException, RemoteException { - URL u = parseURL(name); - String serviceName = getName(u); - return (getRegistry(u).lookup(serviceName)); -} + /** + * Looks for the remote object that is associated with the named service. + * Name and location is given in form of a URL without a scheme: + * + * <pre> + * //host:port/service-name + * </pre> + * + * The port is optional. + * + * @param name the service name and location + * @return Remote-object that implements the named service + * @throws NotBoundException if no object implements the service + * @throws MalformedURLException + * @throws RemoteException + */ + public static Remote lookup(String name) throws NotBoundException, + MalformedURLException, RemoteException + { + URL u = parseURL(name); + String serviceName = getName(u); + return (getRegistry(u).lookup(serviceName)); + } -/** - * Try to bind the given object to the given service name. - * @param name - * @param obj - * @throws AlreadyBoundException - * @throws MalformedURLException - * @throws RemoteException - */ -public static void bind(String name, Remote obj) throws AlreadyBoundException, MalformedURLException, RemoteException { - URL u = parseURL(name); - String serviceName = getName(u); - getRegistry(u).bind(serviceName, obj); -} + /** + * Try to bind the given object to the given service name. + * + * @param name + * @param obj + * @throws AlreadyBoundException + * @throws MalformedURLException + * @throws RemoteException + */ + public static void bind(String name, Remote obj) + throws AlreadyBoundException, MalformedURLException, RemoteException + { + URL u = parseURL(name); + String serviceName = getName(u); + getRegistry(u).bind(serviceName, obj); + } -/** - * Remove a binding for a given service name. - * @param name - * @throws RemoteException - * @throws NotBoundException - * @throws MalformedURLException - */ -public static void unbind(String name) throws RemoteException, NotBoundException, MalformedURLException { - URL u = parseURL(name); - String serviceName = getName(u); - getRegistry(u).unbind(serviceName); -} + /** + * Remove a binding for a given service name. + * + * @param name + * @throws RemoteException + * @throws NotBoundException + * @throws MalformedURLException + */ + public static void unbind(String name) throws RemoteException, + NotBoundException, MalformedURLException + { + URL u = parseURL(name); + String serviceName = getName(u); + getRegistry(u).unbind(serviceName); + } -/** - * Forces the binding between the given Remote-object and the given service name, even - * if there was already an object bound to this name. - * @param name - * @param obj - * @throws RemoteException - * @throws MalformedURLException - */ -public static void rebind(String name, Remote obj) throws RemoteException, MalformedURLException { - URL u = parseURL(name); - String serviceName = getName(u); - getRegistry(u).rebind(serviceName, obj); -} + /** + * Forces the binding between the given Remote-object and the given service + * name, even if there was already an object bound to this name. + * + * @param name + * @param obj + * @throws RemoteException + * @throws MalformedURLException + */ + public static void rebind(String name, Remote obj) throws RemoteException, + MalformedURLException + { + URL u = parseURL(name); + String serviceName = getName(u); + getRegistry(u).rebind(serviceName, obj); + } -/** - * Lists all services at the named registry. - * @param name url that specifies the registry - * @return list of services at the name registry - * @throws RemoteException - * @throws MalformedURLException - */ -public static String[] list(String name) throws RemoteException, MalformedURLException { - return (getRegistry(parseURL(name)).list()); -} + /** + * Lists all services at the named registry. + * + * @param name url that specifies the registry + * @return list of services at the name registry + * @throws RemoteException + * @throws MalformedURLException + */ + public static String[] list(String name) throws RemoteException, + MalformedURLException + { + return (getRegistry(parseURL(name)).list()); + } -private static Registry getRegistry(URL u) throws RemoteException { - if (u.getPort() == -1) { - return (LocateRegistry.getRegistry(u.getHost())); - } - else { - return (LocateRegistry.getRegistry(u.getHost(), u.getPort())); - } -} + private static Registry getRegistry(URL u) throws RemoteException + { + if (u.getPort() == - 1) + { + return (LocateRegistry.getRegistry(u.getHost())); + } + else + { + return (LocateRegistry.getRegistry(u.getHost(), u.getPort())); + } + } /** - * Parses the supplied URL and converts it to use the HTTP - * protocol. From an RMI perspective, the scheme is irrelevant - * and we want to be able to create a URL for which a handler is - * available. - * + * Parses the supplied URL and converts it to use the HTTP protocol. From an + * RMI perspective, the scheme is irrelevant and we want to be able to create + * a URL for which a handler is available. + * * @param name the URL in String form. * @throws MalformedURLException if the URL is invalid. */ - private static URL parseURL(String name) - throws MalformedURLException + private static URL parseURL(String name) throws MalformedURLException { try { - URI uri = new URI(name); - String host = uri.getHost(); - int port = uri.getPort(); - String query = uri.getQuery(); - String path = uri.getPath(); - return new URL("http", - (host == null ? "localhost" : host), - (port == -1 ? 1099 : port), - uri.getPath() + (query == null ? "" : query)); + URI uri = new URI(name); + String host = uri.getHost(); + int port = uri.getPort(); + String query = uri.getQuery(); + String path = uri.getPath(); + return new URL("http", (host == null ? "localhost" : host), + (port == - 1 ? 1099 : port), uri.getPath() + + (query == null ? "" : query)); } catch (URISyntaxException e) { - throw new MalformedURLException("The URL syntax was invalid: " + - e.getMessage()); + throw new MalformedURLException("The URL syntax was invalid: " + + e.getMessage()); } } /** - * Checks that the URL contains a name, and removes any leading - * slashes. - * + * Checks that the URL contains a name, and removes any leading slashes. + * * @param url the URL to check. * @throws MalformedURLException if no name is specified. - */ - private static String getName(URL url) - throws MalformedURLException + */ + private static String getName(URL url) throws MalformedURLException { String filename = url.getFile(); if (filename.length() == 0) @@ -216,5 +231,4 @@ private static Registry getRegistry(URL u) throws RemoteException { return filename.substring(1); return filename; } - } diff --git a/libjava/classpath/java/rmi/NoSuchObjectException.java b/libjava/classpath/java/rmi/NoSuchObjectException.java index 69f7d6c52fb..2943906701b 100644 --- a/libjava/classpath/java/rmi/NoSuchObjectException.java +++ b/libjava/classpath/java/rmi/NoSuchObjectException.java @@ -1,5 +1,6 @@ /* NoSuchObjectException.java -- thrown if the remote object no longer exists - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,9 +44,9 @@ package java.rmi; * obey the semantics of "at most once". * * @author unknown - * @see RemoteObject#toStub(Remote) - * @see UnicastRemoteObject#unexportObject(Remote, boolean) - * @see Activatable#unexportObject(Remote, boolean) + * @see java.rmi.server.RemoteObject#toStub(Remote) + * @see java.rmi.server.UnicastRemoteObject#unexportObject(Remote, boolean) + * @see java.rmi.activation.Activatable#unexportObject(Remote, boolean) * @since 1.1 * @status updated to 1.4 */ diff --git a/libjava/classpath/java/rmi/NotBoundException.java b/libjava/classpath/java/rmi/NotBoundException.java index b8bc0a5320a..03d4adf8f71 100644 --- a/libjava/classpath/java/rmi/NotBoundException.java +++ b/libjava/classpath/java/rmi/NotBoundException.java @@ -1,5 +1,6 @@ /* NotBoundException.java -- attempt to use a registry name with no binding - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,10 +43,10 @@ package java.rmi; * associated binding. * * @author unknown - * @see Naming#lookup(String) - * @see Naming#unbind(String) - * @see Registry#lookup(String) - * @see Registry#unbind(String) + * @see java.rmi.Naming#lookup(String) + * @see java.rmi.Naming#unbind(String) + * @see java.rmi.registry.Registry#lookup(String) + * @see java.rmi.registry.Registry#unbind(String) * @since 1.1 * @status updated to 1.4 */ diff --git a/libjava/classpath/java/rmi/RMISecurityException.java b/libjava/classpath/java/rmi/RMISecurityException.java index a44a67e2a02..6f15af85280 100644 --- a/libjava/classpath/java/rmi/RMISecurityException.java +++ b/libjava/classpath/java/rmi/RMISecurityException.java @@ -1,5 +1,6 @@ /* RMISecurityException.java -- deprecated version of SecurityException - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,11 +39,12 @@ exception statement from your version. */ package java.rmi; /** - * Never thrown, but originally intended to wrap a java.lang.SecurityException. + * Never thrown, but originally intended to wrap a + * {@link java.lang.SecurityException} in the case of RMI. * * @author unknown * @since 1.1 - * @deprecated use {@link SecurityException} instead + * @deprecated use {@link java.lang.SecurityException} instead * @status updated to 1.4 */ public class RMISecurityException extends SecurityException @@ -55,7 +57,7 @@ public class RMISecurityException extends SecurityException /** * Create an exception with a message. * - * @param s the message + * @param n the message * @deprecated no longer needed */ public RMISecurityException(String n) @@ -66,8 +68,8 @@ public class RMISecurityException extends SecurityException /** * Create an exception with a message and a cause. * - * @param s the message - * @param e the cause + * @param n the message + * @param a the cause (ignored) * @deprecated no longer needed */ public RMISecurityException(String n, String a) diff --git a/libjava/classpath/java/rmi/Remote.java b/libjava/classpath/java/rmi/Remote.java index 93c8d0aa127..0306981e96f 100644 --- a/libjava/classpath/java/rmi/Remote.java +++ b/libjava/classpath/java/rmi/Remote.java @@ -1,5 +1,5 @@ /* Remote.java - Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,5 +37,22 @@ exception statement from your version. */ package java.rmi; +/** + * Marker interface for interfaces which methods are invokable + * from outside of this virtual machine through remote method calls. + * <p> + * Remote invokable methods of remote object implementations are specified + * as the methods defined in the implemented remote interfaces. Typically + * remote object implementations are subclasses of the convenience classes + * {@link java.rmi.server.UnicastRemoteObject} or + * {@link java.rmi.activation.Activatable} implementing one or more remote + * interfaces indicating their remotely accessible methods. The convenience + * classes provide implementations for correct remote object creation, + * hash, equals and toString methods. + * </p> + * + * @author unknown + */ public interface Remote { + // marker interface } diff --git a/libjava/classpath/java/rmi/RemoteException.java b/libjava/classpath/java/rmi/RemoteException.java index cbbb26299c3..929bc80f67f 100644 --- a/libjava/classpath/java/rmi/RemoteException.java +++ b/libjava/classpath/java/rmi/RemoteException.java @@ -1,5 +1,6 @@ /* RemoteException.java -- common superclass for exceptions in java.rmi - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -86,7 +87,7 @@ public class RemoteException extends IOException * Create an exception with the given message and cause. * * @param s the message - * @param ex the cause + * @param e the cause */ public RemoteException(String s, Throwable e) { diff --git a/libjava/classpath/java/rmi/StubNotFoundException.java b/libjava/classpath/java/rmi/StubNotFoundException.java index 2f9e0f5ff59..524b418cea1 100644 --- a/libjava/classpath/java/rmi/StubNotFoundException.java +++ b/libjava/classpath/java/rmi/StubNotFoundException.java @@ -1,5 +1,6 @@ /* StubNotFoundException.java -- thrown if a valid stub is not found - Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,8 +42,8 @@ package java.rmi; * Thrown if a valid stub class is not found for an object when it is exported. * * @author unknown - * @see UnicastRemoteObject - * @see Activatable + * @see java.rmi.server.UnicastRemoteObject + * @see java.rmi.activation.Activatable * @since 1.1 * @status updated to 1.4 */ diff --git a/libjava/classpath/java/rmi/dgc/DGC.java b/libjava/classpath/java/rmi/dgc/DGC.java index e78ec2a3aa7..66bfc6dfd62 100644 --- a/libjava/classpath/java/rmi/dgc/DGC.java +++ b/libjava/classpath/java/rmi/dgc/DGC.java @@ -41,11 +41,40 @@ import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.server.ObjID; -public interface DGC extends Remote +/** + * The DGC implementation is used for the server side during the distributed + * garbage collection. This interface contains the two methods: dirty and clean. + * A dirty call is made when a remote reference is unmarshaled in a client. A + * corresponding clean call is made by client it no longer uses that remote + * reference. A reference to a remote object is also automatically released + * after so called lease period that starts after the dirty call is received. It + * is the client's responsibility to renew the leases, by making additional + * dirty calls before such leases expire. + */ +public interface DGC + extends Remote { - Lease dirty (ObjID[] ids, long sequenceNum, Lease lease) - throws RemoteException; + /** + * Mark the given objects referecnes as used on the client side. + * + * @param ids the ids of the used objects. + * @param sequenceNum the number of the call (used to detect and discard late + * calls). + * @param lease the requested lease + * @return the granted lease + */ + Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) + throws RemoteException; - void clean (ObjID[] ids, long sequenceNum, VMID vmid, boolean strong) - throws RemoteException; + /** + * Mark the given objects as no longer used on the client side. + * + * @param ids the ids of the objects that are no longer used. + * @param sequenceNum the number of the call (used to detect and discard late + * @param vmid the VMID of the client. + * @param strong make the "strong" clean call ("strong" calls are scheduled + * after the failed dirty calls). + */ + void clean(ObjID[] ids, long sequenceNum, VMID vmid, boolean strong) + throws RemoteException; } diff --git a/libjava/classpath/java/rmi/dgc/Lease.java b/libjava/classpath/java/rmi/dgc/Lease.java index d3d7f695216..36ff12ad224 100644 --- a/libjava/classpath/java/rmi/dgc/Lease.java +++ b/libjava/classpath/java/rmi/dgc/Lease.java @@ -1,5 +1,6 @@ /* Lease.java Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -7,7 +8,7 @@ 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 @@ -39,29 +40,61 @@ package java.rmi.dgc; import java.io.Serializable; +/** + * A lease object is used to request and grant leases for the remote objects. It + * contains the lease duration and the unique VM indentifier. + */ public final class Lease - implements Serializable { + implements Serializable +{ -static final long serialVersionUID = -5713411624328831948L; + static final long serialVersionUID = - 5713411624328831948L; -private VMID vmid; -private long value; + private VMID vmid; -public Lease(VMID id, long duration) { - vmid = id; - value = duration; -} + private long value; -public VMID getVMID() { - return (vmid); -} + /** + * Create the new lease with the given id and duration + * + * @param id the lease id + * @param duration the lease duration + */ + public Lease(VMID id, long duration) + { + vmid = id; + value = duration; + } -public long getValue() { - return (value); -} + /** + * Get the lease id. + * + * @return the lease id + */ + public VMID getVMID() + { + return (vmid); + } -public String toString() { - return ("[" + vmid.toString() + ", " + Long.toString(value) + "]"); -} + /** + * Get the lease duration + * + * @return the lease duration + */ + public long getValue() + { + return (value); + } + + /** + * Get the string representation of this lease + * + * @return the string represenation (lease id, followed by the lease + * duration). + */ + public String toString() + { + return ("[" + vmid.toString() + ", " + Long.toString(value) + "]"); + } } diff --git a/libjava/classpath/java/rmi/package.html b/libjava/classpath/java/rmi/package.html index a7bf8502056..1d36fe80a89 100644 --- a/libjava/classpath/java/rmi/package.html +++ b/libjava/classpath/java/rmi/package.html @@ -40,7 +40,7 @@ exception statement from your version. --> <head><title>GNU Classpath - java.rmi</title></head> <body> -<p></p> +<p>Provides basic Remote Method Invocation (RMI) interfaces, classes and exceptions.</p> </body> </html> diff --git a/libjava/classpath/java/rmi/registry/Registry.java b/libjava/classpath/java/rmi/registry/Registry.java index 6cd2a04a685..02d8c50cc2a 100644 --- a/libjava/classpath/java/rmi/registry/Registry.java +++ b/libjava/classpath/java/rmi/registry/Registry.java @@ -47,7 +47,29 @@ import java.rmi.RemoteException; public interface Registry extends Remote { int REGISTRY_PORT = 1099; - + + /** + * Find and return the reference to the object that was previously bound + * to the registry by this name. For remote objects, this method returns + * the stub instances, containing the code for remote invocations. + * + * Since jdk 1.5 this method does not longer require the stub class + * (nameImpl_Stub) to be present. If such class is not found, the stub is + * replaced by the dynamically constructed proxy class. No attempt to find + * and load the stubs is made if the system property + * java.rmi.server.ignoreStubClasses is set to true (set to reduce the + * starting time if the stubs are surely not present and exclusively 1.2 + * RMI is used). + * + * @param name the name of the object + * + * @return the reference to that object on that it is possible to invoke + * the (usually remote) object methods. + * + * @throws RemoteException + * @throws NotBoundException + * @throws AccessException + */ Remote lookup(String name) throws RemoteException, NotBoundException, AccessException; diff --git a/libjava/classpath/java/rmi/server/RMIClassLoader.java b/libjava/classpath/java/rmi/server/RMIClassLoader.java index f8997fd7e09..33c44198d37 100644 --- a/libjava/classpath/java/rmi/server/RMIClassLoader.java +++ b/libjava/classpath/java/rmi/server/RMIClassLoader.java @@ -38,10 +38,13 @@ exception statement from your version. */ package java.rmi.server; +import gnu.classpath.ServiceFactory; +import gnu.classpath.SystemProperties; import gnu.java.rmi.server.RMIClassLoaderImpl; import java.net.MalformedURLException; import java.net.URL; +import java.util.Iterator; /** * This class provides a set of public static utility methods for supporting @@ -84,6 +87,16 @@ public class RMIClassLoader return spi.loadClass(codebase, name, defaultLoader); } + public static Class loadProxyClass (String codeBase, String[] interfaces, + ClassLoader defaultLoader) + throws MalformedURLException, ClassNotFoundException + { + RMIClassLoaderSpi spi = getProviderInstance(); + if (spi == null) + spi = getDefaultProviderInstance(); + return spi.loadProxyClass(codeBase, interfaces, defaultLoader); + } + /** * Loads a class from <code>codeBase</code>. * @@ -171,7 +184,20 @@ public class RMIClassLoader */ private static RMIClassLoaderSpi getProviderInstance() { - // TODO: Do something more useful here. - return null; + // If the user asked for the default, return it. We do a special + // check here because our standard service lookup function does not + // handle this -- nor should it. + String prop = SystemProperties.getProperty("java.rmi.server.RMIClassLoaderSpi"); + if ("default".equals(prop)) + return null; + Iterator it = ServiceFactory.lookupProviders(RMIClassLoaderSpi.class, + null); + if (it == null || ! it.hasNext()) + return null; + // FIXME: the spec says we ought to throw an Error of some kind if + // the specified provider is not suitable for some reason. However + // our service factory simply logs the problem and moves on to the next + // provider in this situation. + return (RMIClassLoaderSpi) it.next(); } } diff --git a/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java b/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java new file mode 100644 index 00000000000..afd1d592715 --- /dev/null +++ b/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java @@ -0,0 +1,221 @@ +/* RemoteObjectInvocationHandler.java -- RMI stub replacement. + 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 java.rmi.server; + +import gnu.java.rmi.server.RMIHashes; + +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.UnexpectedException; +import java.rmi.registry.Registry; +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteRef; +import java.rmi.server.UnicastRemoteObject; +import java.util.Hashtable; + +/** + * Together with dynamic proxy instance, this class replaces the generated RMI + * stub (*_Stub) classes that (following 1.5 specification) should be no longer + * required. It is unusual to use the instances of this class directly in the + * user program. Such instances are automatically created and returned by + * {@link Registry} or {@link UnicastRemoteObject} methods if the remote + * reference is known but the corresponding stub class is not accessible. + * + * @see Registry#lookup + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class RemoteObjectInvocationHandler extends RemoteObject implements + InvocationHandler, Remote, Serializable +{ + /** + * Use the jdk 1.5 SUID for interoperability. + */ + static final long serialVersionUID = 2L; + + /** + * The RMI method hash codes, computed once as described in the section 8.3 + * of the Java Remote Method Invocation (RMI) Specification. + */ + static Hashtable methodHashCodes = new Hashtable(); + + /** + * The empty class array to define parameters of .hashCode and .toString. + */ + static final Class[] noArgsC = new Class[0]; + + /** + * The class array to define parameters of .equals + */ + static final Class[] anObjectC = new Class[] { Object.class }; + + /** + * Construct the remote invocation handler that forwards calls to the given + * remote object. + * + * @param reference the reference to the remote object where the method + * calls should be forwarded. + */ + public RemoteObjectInvocationHandler(RemoteRef reference) + { + super(reference); + } + + /** + * Invoke the remote method. When the known method is invoked on a created RMI + * stub proxy class, the call is delivered to this method and then transferred + * to the {@link RemoteRef#invoke(Remote, Method, Object[], long)} of the + * remote reference that was passed in constructor. The methods are handled as + * following: + * <ul> + * <li> The toString() method is delegated to the passed proxy instance.</li> + * <li>The .equals method only returns true if the passed object is an + * instance of proxy class and its invocation handler is equal to this + * invocation handles.</li> + * <li>The .hashCode returns the hashCode of this invocation handler (if the.</li> + * <li>All other methods are converted to remote calls and forwarded to the + * remote reference. </li> + * </ul> + * + * @param proxyInstance + * the instance of the proxy stub + * @param method + * the method being invoked + * @param parameters + * the method parameters + * @return the method return value, returned by RemoteRef.invoke + * @throws IllegalAccessException + * if the passed proxy instance does not implement Remote interface. + * @throws UnexpectedException + * if remote call throws some exception, not listed in the + * <code>throws</code> clause of the method being called. + * @throws Throwable + * that is thrown by remote call, if that exception is listend in + * the <code>throws</code> clause of the method being called. + */ + public Object invoke(Object proxyInstance, Method method, Object[] parameters) + throws Throwable + { + if (!(proxyInstance instanceof Remote)) + { + String name = proxyInstance == null ? "null" + : proxyInstance.getClass().getName(); + throw new IllegalAccessException(name + " does not implement " + + Remote.class.getName()); + } + + String name = method.getName(); + switch (name.charAt(0)) + { + case 'e': + if (parameters.length == 1 && name.equals("equals") + && method.getParameterTypes()[0].equals(Object.class)) + { + if (parameters[0] instanceof Proxy) + { + Object handler = Proxy.getInvocationHandler(parameters[0]); + if (handler == null) + return Boolean.FALSE; + else + return handler.equals(this) ? Boolean.TRUE : Boolean.FALSE; + } + else + return Boolean.FALSE; + } + break; + case 'h': + if (parameters.length == 0 && name.equals("hashCode")) + { + int hashC = Proxy.getInvocationHandler(proxyInstance).hashCode(); + return new Integer(hashC); + } + break; + case 't': + if (parameters.length == 0 && name.equals("toString")) + return proxyInstance.toString(); + break; + default: + break; + } + + Long hash = (Long) methodHashCodes.get(method); + if (hash == null) + { + hash = new Long(RMIHashes.getMethodHash(method)); + methodHashCodes.put(method, hash); + } + + try + { + return getRef().invoke((Remote) proxyInstance, method, parameters, + hash.longValue()); + } + catch (RuntimeException exception) + { + // RuntimeException is always supported. + throw exception; + } + catch (RemoteException exception) + { + // All remote methods can throw RemoteException. + throw exception; + } + catch (Error exception) + { + throw exception; + } + catch (Exception exception) + { + Class[] exceptions = method.getExceptionTypes(); + Class exceptionClass = exception.getClass(); + + for (int i = 0; i < exceptions.length; i++) + { + if (exceptions[i].equals(exceptionClass)) + throw exception; + } + throw new UnexpectedException(method.getName(), exception); + } + } + +} diff --git a/libjava/classpath/java/rmi/server/RemoteRef.java b/libjava/classpath/java/rmi/server/RemoteRef.java index f33f9d374c3..8bdb6633040 100644 --- a/libjava/classpath/java/rmi/server/RemoteRef.java +++ b/libjava/classpath/java/rmi/server/RemoteRef.java @@ -1,5 +1,6 @@ /* RemoteRef.java -- - Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,8 +45,16 @@ import java.lang.reflect.Method; import java.rmi.Remote; import java.rmi.RemoteException; +/** + * Represents a handler to the remote object. Each instance of the + * {@link RemoteStub} contains such handler and uses it to invoke remote + * methods via {@link #invoke(Remote, Method, Object[], long)}. + */ public interface RemoteRef extends Externalizable { + /** + * Indicates compatibility with JDK 1.1.* + */ long serialVersionUID = 3632638527362204081L; /** @@ -55,29 +64,74 @@ public interface RemoteRef extends Externalizable String packagePrefix = "sun.rmi.server"; /** - * @deprecated + * @deprecated use {@link #invoke(Remote, Method, Object[], long)} instead. */ void invoke (RemoteCall call) throws Exception; - Object invoke (Remote obj, Method method, Object[] params, long opnum) + /** + * Invoke a method. This method either returns the result of remote invocation + * or throws RemoteException if the remote call failed. Other exceptions may + * be thrown if some problem has occured in the application level. + * + * @param obj the object, containing the remote reference (for instance, + * remote stub, generated by rmic). + * @param method the method to invoke + * @param params the method parameters + * @param methodHash a persistent hash code that can be used to represent a + * method + * @return the result of the remote invocation + * @throws RemoteException if the remote call has failed + * @throws Exception if one is raised at the application level + */ + Object invoke (Remote obj, Method method, Object[] params, long methodHash) throws Exception; /** - * @deprecated + * @deprecated use {@link #invoke(Remote, Method, Object[], long)} instead. */ RemoteCall newCall (RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException; /** - * @deprecated + * @deprecated use {@link #invoke(Remote, Method, Object[], long)} instead. */ void done (RemoteCall call) throws RemoteException; + /** + * Compare two remote objects for equality. The references are equal if + * they point to the same remote object. + * + * @param ref the reference to compare. + * + * @return true if this and passed references both point to the same remote + * object, false otherwise. + */ boolean remoteEquals (RemoteRef ref); + /** + * Get the hashcode for a remote object. Two remote object stubs, referring + * to the same remote object, have the same hash code. + * + * @return the hashcode of the remote object + */ int remoteHashCode(); + + /** + * Returns the class name of the reference type that must be written to the + * given stream. When writing, this returned name is passed first, and + * the reference.writeExternal(out) writes the reference specific data. + * + * @param out the stream, where the data must be written + * + * @return the class name. + */ String getRefClass (ObjectOutput out); + /** + * Get the string representation of this remote reference. + * + * @return the string representation. + */ String remoteToString(); } diff --git a/libjava/classpath/java/rmi/server/RemoteStub.java b/libjava/classpath/java/rmi/server/RemoteStub.java index 18c614b54a8..d6dff7fadc8 100644 --- a/libjava/classpath/java/rmi/server/RemoteStub.java +++ b/libjava/classpath/java/rmi/server/RemoteStub.java @@ -37,21 +37,40 @@ exception statement from your version. */ package java.rmi.server; +/** + * This is a base class for the automatically generated RMI stubs. + */ public abstract class RemoteStub extends RemoteObject { + /** + * Use serialVersionUID for interoperability. + */ static final long serialVersionUID = -1585587260594494182l; - + + /** + * Constructs the remote stub with no reference set. + */ protected RemoteStub () { super (); } - + + /** + * Constructs the remote stub that uses given remote reference for the + * method invocations. + * + * @param ref the remote reference for the method invocation. + */ protected RemoteStub (RemoteRef ref) { super (ref); } /** + * Sets the given remote reference for the given stub. This method is + * deprecated. Pass the stub remote reference to the RemoteStub + * constructor instead. + * * @deprecated */ protected static void setRef (RemoteStub stub, RemoteRef ref) diff --git a/libjava/classpath/java/rmi/server/UnicastRemoteObject.java b/libjava/classpath/java/rmi/server/UnicastRemoteObject.java index dbe25bda3fd..31bf8802301 100644 --- a/libjava/classpath/java/rmi/server/UnicastRemoteObject.java +++ b/libjava/classpath/java/rmi/server/UnicastRemoteObject.java @@ -1,5 +1,6 @@ /* UnicastRemoteObject.java -- - Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,61 +45,175 @@ import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; +/** + * This class obtains stub that communicates with the remote object. + */ public class UnicastRemoteObject extends RemoteServer { -private static final long serialVersionUID = 4974527148936298033L; -//The following serialized fields are from Java API Documentation "Serialized form" -private int port = 0; -private RMIClientSocketFactory csf = null; -private RMIServerSocketFactory ssf = null; + /** + * Use SVUID for interoperability. + */ + private static final long serialVersionUID = 4974527148936298033L; -protected UnicastRemoteObject() throws RemoteException { - this(0); -} + //The following serialized fields are from Java API Documentation + // "Serialized form" + + /** + * The port, on that the created remote object becomes available, + * zero meaning the anonymous port. + */ + private int port; + + /** + * The client socket factory for producing client sockets, used by this + * object. + */ + private RMIClientSocketFactory csf; + + /** + * The server socket factory for producing server sockets, used by this + * object. + */ + private RMIServerSocketFactory ssf; -protected UnicastRemoteObject(int port) throws RemoteException { - this(port, RMISocketFactory.getSocketFactory(), RMISocketFactory.getSocketFactory()); -} + /** + * Create and export new remote object without specifying the port value. + * + * @throws RemoteException if the attempt to export the object failed. + */ + protected UnicastRemoteObject() + throws RemoteException + { + this(0); + } + + /** + * Create and export the new remote object, making it available at the + * given port, local host. + * + * @param port the port, on that the object should become available. + * Zero means anonymous port. + * + * @throws RemoteException if the attempt to export the object failed. + */ + protected UnicastRemoteObject(int port) + throws RemoteException + { + this(port, RMISocketFactory.getSocketFactory(), + RMISocketFactory.getSocketFactory()); + } -protected UnicastRemoteObject(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { - this.port = port; - //Is RMIXXXSocketFactory serializable - //this.csf = csf; - //this.ssf = ssf; - this.ref = new UnicastServerRef(new ObjID(), port, ssf); - exportObject(this); -} + /** + * Create and export the new remote object, making it available at the + * given port, using sockets, produced by the specified factories. + * + * @param port the port, on that the object should become available. + * Zero means anonymous port. + * + * @param clientSocketFactory the client socket factory + * @param serverSocketFactory the server socket factory + * + * @throws RemoteException if the attempt to export the object failed. + */ + protected UnicastRemoteObject(int port, + RMIClientSocketFactory clientSocketFactory, + RMIServerSocketFactory serverSocketFactory) + throws RemoteException + { + this.port = port; + //Is RMIXXXSocketFactory serializable + //this.csf = csf; + //this.ssf = ssf; + this.ref = new UnicastServerRef(new ObjID(), port, serverSocketFactory); + exportObject(this, port); + } -protected UnicastRemoteObject(RemoteRef ref) throws RemoteException { - super((UnicastServerRef)ref); - exportObject(this); -} + protected UnicastRemoteObject(RemoteRef ref) + throws RemoteException + { + super((UnicastServerRef) ref); + exportObject(this, 0); + } -public Object clone() throws CloneNotSupportedException { + public Object clone() + throws CloneNotSupportedException + { throw new Error("Not implemented"); -} - -public static RemoteStub exportObject(Remote obj) throws RemoteException { - UnicastServerRef sref = (UnicastServerRef)((RemoteObject)obj).getRef(); - return (sref.exportObject(obj)); -} + } + + /** + * Export object, making it available for the remote calls at the + * anonymous port. + * + * This method returns the instance of the abstract class, not an interface. + * Hence it will not work with the proxy stubs that are supported since + * jdk 1.5 (such stubs cannot be derived from the RemoteStub). Only use + * this method if you are sure that the stub class will be accessible. + * + * @param obj the object being exported. + * + * @return the remote object stub + * + * @throws RemoteException if the attempt to export the object failed. + */ + public static RemoteStub exportObject(Remote obj) + throws RemoteException + { + return (RemoteStub) exportObject(obj, 0); + } - public static Remote exportObject(Remote obj, int port) throws RemoteException + /** + * Export object, making it available for the remote calls at the + * specified port. + * + * Since jdk 1.5 this method does not longer require the stub class to be + * present. If such class is not found, the stub is replaced by the + * dynamically constructed proxy class. No attempt to find and load the stubs + * is made if the system property java.rmi.server.ignoreStubClasses + * is set to true (set to reduce the starting time if the stubs are + * surely not present and exclusively 1.2 RMI is used). + * + * @param obj the object being exported. + * @param port the remote object port + * + * @return the remote object stub + * + * @throws RemoteException if the attempt to export the object failed. + */ + public static Remote exportObject(Remote obj, int port) + throws RemoteException { return exportObject(obj, port, null); } - - static Remote exportObject(Remote obj, int port, RMIServerSocketFactory ssf) - throws RemoteException + + /** + * Create and export the new remote object, making it available at the + * given port, using sockets, produced by the specified factories. + * + * Since jdk 1.5 this method does not longer require the stub class to be + * present. If such class is not found, the stub is replaced by the + * dynamically constructed proxy class. No attempt to find and load the stubs + * is made if the system property java.rmi.server.ignoreStubClasses + * is set to true (set to reduce the starting time if the stubs are + * surely not present and exclusively 1.2 RMI is used). + * + * @param port the port, on that the object should become available. + * Zero means anonymous port. + * + * @param serverSocketFactory the server socket factory + */ + static Remote exportObject(Remote obj, int port, + RMIServerSocketFactory serverSocketFactory) + throws RemoteException { UnicastServerRef sref = null; if (obj instanceof RemoteObject) - sref = (UnicastServerRef)((RemoteObject)obj).getRef (); - if(sref == null) - { - sref = new UnicastServerRef(new ObjID (), port, ssf); - } - Remote stub = sref.exportObject (obj); + sref = (UnicastServerRef) ((RemoteObject) obj).getRef(); + + if (sref == null) + sref = new UnicastServerRef(new ObjID(), port, serverSocketFactory); + + Remote stub = sref.exportObject(obj); addStub(obj, stub); return stub; } @@ -106,8 +221,9 @@ public static RemoteStub exportObject(Remote obj) throws RemoteException { /** * FIXME */ - public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, - RMIServerSocketFactory ssf) + public static Remote exportObject(Remote obj, int port, + RMIClientSocketFactory csf, + RMIServerSocketFactory ssf) throws RemoteException { return (exportObject(obj, port, ssf)); @@ -118,14 +234,15 @@ public static RemoteStub exportObject(Remote obj) throws RemoteException { { if (obj instanceof RemoteObject) { - deleteStub(obj); - UnicastServerRef sref = (UnicastServerRef)((RemoteObject)obj).getRef(); - return sref.unexportObject(obj, force); + deleteStub(obj); + UnicastServerRef sref = + (UnicastServerRef) ((RemoteObject) obj).getRef(); + return sref.unexportObject(obj, force); } else { - //FIX ME - ; + // FIXME + ; } return true; } diff --git a/libjava/classpath/java/security/AlgorithmParameterGenerator.java b/libjava/classpath/java/security/AlgorithmParameterGenerator.java index 5dc9e3bb274..e33fbaf81db 100644 --- a/libjava/classpath/java/security/AlgorithmParameterGenerator.java +++ b/libjava/classpath/java/security/AlgorithmParameterGenerator.java @@ -43,38 +43,15 @@ import gnu.java.security.Engine; import java.security.spec.AlgorithmParameterSpec; /** - * <p>The <code>AlgorithmParameterGenerator</code> class is used to generate a - * set of parameters to be used with a certain algorithm. Parameter generators - * are constructed using the <code>getInstance()</code> factory methods (static - * methods that return instances of a given class).</p> - * - * <p>The object that will generate the parameters can be initialized in two - * different ways: in an algorithm-independent manner, or in an - * algorithm-specific manner:</p> - * - * <ul> - * <li>The algorithm-independent approach uses the fact that all parameter - * generators share the concept of a <i>"size"</i> and a <i>source of - * randomness</i>. The measure of <i>size</i> is universally shared by all - * algorithm parameters, though it is interpreted differently for different - * algorithms. For example, in the case of parameters for the <i>DSA</i> - * algorithm, <i>"size"</i> corresponds to the size of the prime modulus (in - * bits). When using this approach, algorithm-specific parameter generation - * values - if any - default to some standard values, unless they can be - * derived from the specified size.</li> - * <li>The other approach initializes a parameter generator object using - * algorithm-specific semantics, which are represented by a set of - * algorithm-specific parameter generation values. To generate Diffie-Hellman - * system parameters, for example, the parameter generation values usually - * consist of the size of the prime modulus and the size of the random - * exponent, both specified in number of bits.</li> - * </ul> - * + * <code>AlgorithmParameterGenerator</code> is used to generate algorithm + * parameters for specified algorithms. + * * <p>In case the client does not explicitly initialize the - * <code>AlgorithmParameterGenerator</code> (via a call to an <code>init()</code> - * method), each provider must supply (and document) a default initialization. - * For example, the <b>GNU</b> provider uses a default modulus prime size of - * <code>1024</code> bits for the generation of <i>DSA</i> parameters. + * <code>AlgorithmParameterGenerator</code> (via a call to an + * <code>init()</code> method), each provider must supply (and document) a + * default initialization. For example, the <b>GNU</b> provider uses a default + * modulus prime size of <code>1024</code> bits for the generation of <i>DSA</i> + * parameters. * * @author Mark Benvenuto * @since 1.2 @@ -92,11 +69,14 @@ public class AlgorithmParameterGenerator private String algorithm; /** - * Creates an <code>AlgorithmParameterGenerator</code> object. - * - * @param paramGenSpi the delegate. - * @param provider the provider. - * @param algorithm the algorithm. + * Constructs a new instance of <code>AlgorithmParameterGenerator</code>. + * + * @param paramGenSpi + * the generator to use. + * @param provider + * the provider to use. + * @param algorithm + * the algorithm to use. */ protected AlgorithmParameterGenerator(AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider, @@ -107,30 +87,21 @@ public class AlgorithmParameterGenerator this.algorithm = algorithm; } - /** - * Returns the standard name of the algorithm this parameter generator is - * associated with. - * - * @return the string name of the algorithm. - */ + /** @return the name of the algorithm. */ public final String getAlgorithm() { return algorithm; } /** - * Generates an <code>AlgorithmParameterGenerator</code> object that - * implements the specified digest algorithm. If the default provider package - * provides an implementation of the requested digest algorithm, an instance - * of <code>AlgorithmParameterGenerator</code> containing that implementation - * is returned. If the algorithm is not available in the default package, - * other packages are searched. - * - * @param algorithm the string name of the algorithm this parameter generator - * is associated with. - * @return the new <code>AlgorithmParameterGenerator</code> object. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * environment. + * Returns a new <code>AlgorithmParameterGenerator</code> instance which + * generates algorithm parameters for the specified algorithm. + * + * @param algorithm + * the name of algorithm to use. + * @return the new instance. + * @throws NoSuchAlgorithmException + * if <code>algorithm</code> is not implemented by any provider. */ public static AlgorithmParameterGenerator getInstance(String algorithm) throws NoSuchAlgorithmException @@ -150,20 +121,18 @@ public class AlgorithmParameterGenerator } /** - * Generates an <code>AlgorithmParameterGenerator</code> object for the - * requested algorithm, as supplied from the specified provider, if such a - * parameter generator is available from the provider. - * - * @param algorithm the string name of the algorithm. - * @param provider the string name of the provider. - * @return the new <code>AlgorithmParameterGenerator</code> object. - * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not - * available from the <code>provider</code>. - * @throws NoSuchProviderException if the <code>provider</code> is not - * available in the environment. - * @throws IllegalArgumentException if the <code>provider</code> name is - * <code>null</code> or empty. - * @see Provider + * Returns a new <code>AlgorithmParameterGenerator</code> instance which + * generates algorithm parameters for the specified algorithm. + * + * @param algorithm + * the name of algorithm to use. + * @param provider + * the name of the {@link Provider} to use. + * @return the new instance. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the named provider. + * @throws NoSuchProviderException + * if the named provider was not found. */ public static AlgorithmParameterGenerator getInstance(String algorithm, String provider) @@ -180,17 +149,16 @@ public class AlgorithmParameterGenerator } /** - * Generates an AlgorithmParameterGenerator object for the requested - * algorithm, as supplied from the specified provider, if such a parameter - * generator is available from the provider. Note: the <code>provider</code> - * doesn't have to be registered. - * - * @param algorithm the string name of the algorithm. - * @param provider the provider. - * @return the new AlgorithmParameterGenerator object. - * @throws NoSuchAlgorithmException if the algorithm is not available from - * the provider. - * @throws IllegalArgumentException if the provider is null. + * Returns a new <code>AlgorithmParameterGenerator</code> instance which + * generates algorithm parameters for the specified algorithm. + * + * @param algorithm + * the name of algorithm to use. + * @param provider + * the {@link Provider} to use. + * @return the new instance. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by {@link Provider}. * @since 1.4 * @see Provider */ @@ -218,24 +186,18 @@ public class AlgorithmParameterGenerator } } - /** - * Returns the provider of this algorithm parameter generator object. - * - * @return the provider of this algorithm parameter generator object. - */ + /** @return the {@link Provider} of this generator. */ public final Provider getProvider() { return provider; } /** - * Initializes this parameter generator for a certain <i>size</i>. To create - * the parameters, the {@link SecureRandom} implementation of the - * highest-priority installed provider is used as the source of randomness. - * (If none of the installed providers supply an implementation of - * {@link SecureRandom}, a system-provided source of randomness is used.) - * - * @param size the size (number of bits). + * Initializes this instance with the specified size. Since no source of + * randomness is supplied, a default one will be used. + * + * @param size + * size (in bits) to use. */ public final void init(int size) { @@ -243,11 +205,13 @@ public class AlgorithmParameterGenerator } /** - * Initializes this parameter generator for a certain size and source of + * Initializes this instance with the specified key-size and source of * randomness. - * - * @param size the size (number of bits). - * @param random the source of randomness. + * + * @param size + * the size (in bits) to use. + * @param random + * the {@link SecureRandom} to use. */ public final void init(int size, SecureRandom random) { @@ -255,33 +219,30 @@ public class AlgorithmParameterGenerator } /** - * Initializes this parameter generator with a set of algorithm-specific - * parameter generation values. To generate the parameters, the {@link - * SecureRandom} implementation of the highest-priority installed provider is - * used as the source of randomness. (If none of the installed providers - * supply an implementation of {@link SecureRandom}, a system-provided source - * of randomness is used.) - * - * @param genParamSpec the set of algorithm-specific parameter generation - * values. - * @throws InvalidAlgorithmParameterException if the given parameter - * generation values are inappropriate for this parameter generator. + * Initializes this instance with the specified {@link AlgorithmParameterSpec}. + * Since no source of randomness is supplied, a default one will be used. + * + * @param genParamSpec + * the {@link AlgorithmParameterSpec} to use. + * @throws InvalidAlgorithmParameterException + * if <code>genParamSpec</code> is invalid. */ public final void init(AlgorithmParameterSpec genParamSpec) - throws InvalidAlgorithmParameterException + throws InvalidAlgorithmParameterException { init(genParamSpec, new SecureRandom()); } /** - * Initializes this parameter generator with a set of algorithm-specific - * parameter generation values. - * - * @param genParamSpec the set of algorithm-specific parameter generation - * values. - * @param random the source of randomness. - * @throws InvalidAlgorithmParameterException if the given parameter - * generation values are inappropriate for this parameter generator. + * Initializes this instance with the specified {@link AlgorithmParameterSpec} + * and source of randomness. + * + * @param genParamSpec + * the {@link AlgorithmParameterSpec} to use. + * @param random + * the {@link SecureRandom} to use. + * @throws InvalidAlgorithmParameterException + * if <code>genParamSpec</code> is invalid. */ public final void init(AlgorithmParameterSpec genParamSpec, SecureRandom random) @@ -290,11 +251,7 @@ public class AlgorithmParameterGenerator paramGenSpi.engineInit(genParamSpec, random); } - /** - * Generates the parameters. - * - * @return the new {@link AlgorithmParameters} object. - */ + /** @return a new instance of {@link AlgorithmParameters}. */ public final AlgorithmParameters generateParameters() { return paramGenSpi.engineGenerateParameters(); diff --git a/libjava/classpath/java/security/AlgorithmParameters.java b/libjava/classpath/java/security/AlgorithmParameters.java index 038fbb4bd64..c4655aefacb 100644 --- a/libjava/classpath/java/security/AlgorithmParameters.java +++ b/libjava/classpath/java/security/AlgorithmParameters.java @@ -45,36 +45,9 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; /** - * <p>This class is used as an opaque representation of cryptographic - * parameters.</p> - * - * <p>An <code>AlgorithmParameters</code> object for managing the parameters - * for a particular algorithm can be obtained by calling one of the - * <code>getInstance()</code> factory methods (static methods that return - * instances of a given class).</p> - * - * <p>There are two ways to request such an implementation: by specifying - * either just an algorithm name, or both an algorithm name and a package - * provider.</p> - * - * <ul> - * <li>If just an algorithm name is specified, the system will determine if - * there is an AlgorithmParameters implementation for the algorithm requested - * available in the environment, and if there is more than one, if there is - * a preferred one.</li> - * <li>If both an algorithm name and a package provider are specified, the - * system will determine if there is an implementation in the package - * requested, and throw an exception if there is not.</li> - * </ul> - * - * <p>Once an <code>AlgorithmParameters</code> object is returned, it must be - * initialized via a call to <code>init()</code>, using an appropriate - * parameter specification or parameter encoding.</p> - * - * <p>A transparent parameter specification is obtained from an - * <code>AlgorithmParameters</code> object via a call to - * <code>getParameterSpec()</code>, and a byte encoding of the parameters is - * obtained via a call to <code>getEncoded()</code>.</p> + * <code>AlgorithmParameters</code> is an Algorithm Parameters class which + * provides an interface through which the user can manage the parameters of an + * Algorithm. * * @author Mark Benvenuto * @since 1.2 @@ -92,11 +65,14 @@ public class AlgorithmParameters private String algorithm; /** - * Creates an <code>AlgorithmParameters</code> object. - * - * @param paramSpi the delegate. - * @param provider the provider. - * @param algorithm the algorithm. + * Constructs a new instance of <code>AlgorithmParameters</code>. + * + * @param paramSpi + * the engine to use. + * @param provider + * the provider to use. + * @param algorithm + * the algorithm to use. */ protected AlgorithmParameters(AlgorithmParametersSpi paramSpi, Provider provider, String algorithm) @@ -106,32 +82,24 @@ public class AlgorithmParameters this.algorithm = algorithm; } - /** - * Returns the name of the algorithm associated with this parameter object. - * - * @return the algorithm name. - */ + /** @return A string with the name of the algorithm used. */ public final String getAlgorithm() { return algorithm; } /** - * <p>Generates a parameter object for the specified algorithm.</p> - * - * <p>If the default provider package provides an implementation of the - * requested algorithm, an instance of <code>AlgorithmParameters</code> - * containing that implementation is returned. If the algorithm is not - * available in the default package, other packages are searched.</p> - * - * <p>The returned parameter object must be initialized via a call to - * <code>init()</code>, using an appropriate parameter specification or - * parameter encoding.</p> - * - * @param algorithm the name of the algorithm requested. - * @return the new parameter object. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * environment. + * Returns a new instance of <code>AlgorithmParameters</code> representing + * the specified algorithm parameters. + * + * <p>The returned <code>AlgorithmParameters</code> must still be initialized + * with an <code>init()</code> method.</p> + * + * @param algorithm + * the algorithm to use. + * @return the new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by any provider. */ public static AlgorithmParameters getInstance(String algorithm) throws NoSuchAlgorithmException @@ -152,23 +120,24 @@ public class AlgorithmParameters } /** - * <p>Generates a parameter object for the specified algorithm, as supplied - * by the specified provider, if such an algorithm is available from the - * provider.</p> - * - * <p>The returned parameter object must be initialized via a call to - * <code>init()</code>, using an appropriate parameter specification or - * parameter encoding.</p> - * - * @param algorithm the name of the algorithm requested. - * @param provider the name of the provider. - * @return the new parameter object. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * package supplied by the requested provider. - * @throws NoSuchProviderException if the provider is not available in the - * environment. - * @throws IllegalArgumentException if the provider name is null or empty. - * @see Provider + * Returns a new instance of <code>AlgorithmParameters</code> representing + * the specified algorithm parameters from a named provider. + * + * <p>The returned <code>AlgorithmParameters</code> must still be intialized + * with an <code>init()</code> method.</p> + * + * @param algorithm + * the algorithm to use. + * @param provider + * the name of the {@link Provider} to use. + * @return the new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the named provider. + * @throws NoSuchProviderException + * if the named provider was not found. + * @throws IllegalArgumentException + * if <code>provider</code> is <code>null</code> or is an empty + * string. */ public static AlgorithmParameters getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException @@ -184,18 +153,21 @@ public class AlgorithmParameters } /** - * Generates an <code>AlgorithmParameterGenerator</code> object for the - * requested algorithm, as supplied from the specified provider, if such a - * parameter generator is available from the provider. Note: the - * <code>provider</code> doesn't have to be registered. - * - * @param algorithm the string name of the algorithm. - * @param provider the provider. - * @return the new <code>AlgorithmParameterGenerator</code> object. - * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not - * available from the <code>provider</code>. - * @throws IllegalArgumentException if the <code>provider</code> is - * <code>null</code>. + * Returns a new instance of <code>AlgorithmParameters</code> representing + * the specified algorithm parameters from the specified {@link Provider}. + * + * <p>The returned <code>AlgorithmParameters</code> must still be intialized + * with an <code>init()</code> method.</p> + * + * @param algorithm + * the algorithm to use. + * @param provider + * the {@link Provider} to use. + * @return the new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the {@link Provider}. + * @throws IllegalArgumentException + * if <code>provider</code> is <code>null</code>. * @since 1.4 */ public static AlgorithmParameters getInstance(String algorithm, @@ -221,24 +193,19 @@ public class AlgorithmParameters } } - /** - * Returns the provider of this parameter object. - * - * @return the provider of this parameter object. - */ + /** @return the provider of this parameter object. */ public final Provider getProvider() { return provider; } /** - * Initializes this parameter object using the parameters specified in - * <code>paramSpec</code>. - * - * @param paramSpec the parameter specification. - * @throws InvalidParameterSpecException if the given parameter specification - * is inappropriate for the initialization of this parameter object, or if - * this parameter object has already been initialized. + * Initializes the engine with the specified {@link AlgorithmParameterSpec}. + * + * @param paramSpec + * A {@link AlgorithmParameterSpec} to use. + * @throws InvalidParameterSpecException + * if <code>paramSpec</code> is invalid. */ public final void init(AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException @@ -247,13 +214,15 @@ public class AlgorithmParameters } /** - * Imports the specified parameters and decodes them according to the primary - * decoding format for parameters. The primary decoding format for parameters - * is ASN.1, if an ASN.1 specification for this type of parameters exists. - * - * @param params the encoded parameters. - * @throws IOException on decoding errors, or if this parameter object has - * already been initialized. + * Initializes the engine with the specified parameters stored in the byte + * array and decodes them according to the ASN.1 specification. If the ASN.1 + * specification exists then it succeeds otherwise an {@link IOException} is + * thrown. + * + * @param params + * the parameters to use. + * @throws IOException + * if a decoding error occurs. */ public final void init(byte[]params) throws IOException { @@ -261,15 +230,18 @@ public class AlgorithmParameters } /** - * Imports the parameters from params and decodes them according to the - * specified decoding scheme. If <code>format</code> is <code>null</code>, - * the primary decoding format for parameters is used. The primary decoding - * format is ASN.1, if an ASN.1 specification for these parameters exists. - * - * @param params the encoded parameters. - * @param format the name of the decoding scheme. - * @throws IOException on decoding errors, or if this parameter object has - * already been initialized. + * Initializes the engine with the specified parameters stored in the byte + * array and decodes them according to the specified decoding specification. + * If <code>format</code> is <code>null</code>, then this method decodes the + * byte array using the ASN.1 specification if it exists, otherwise it throws + * an {@link IOException}. + * + * @param params + * the parameters to use. + * @param format + * the name of decoding format to use. + * @throws IOException + * if a decoding error occurs. */ public final void init(byte[]params, String format) throws IOException { @@ -277,19 +249,14 @@ public class AlgorithmParameters } /** - * Returns a (transparent) specification of this parameter object. - * <code>paramSpec</code> identifies the specification class in which the - * parameters should be returned. It could, for example, be - * <code>DSAParameterSpec.class</code>, to indicate that the parameters should - * be returned in an instance of the {@link java.security.spec.DSAParameterSpec} - * class. - * - * @param paramSpec the specification class in which the parameters should be - * returned. + * Returns a new instance of <code>AlgorithmParameters</code> as a + * designated parameter specification {@link Class}. + * + * @param paramSpec + * the {@link Class} to use. * @return the parameter specification. - * @throws InvalidParameterSpecException if the requested parameter - * specification is inappropriate for this parameter object, or if this - * parameter object has not been initialized. + * @throws InvalidParameterSpecException + * if <code>paramSpec</code> is invalid. */ public final AlgorithmParameterSpec getParameterSpec(Class paramSpec) throws InvalidParameterSpecException @@ -298,13 +265,10 @@ public class AlgorithmParameters } /** - * Returns the parameters in their primary encoding format. The primary - * encoding format for parameters is ASN.1, if an ASN.1 specification for - * this type of parameters exists. - * - * @return the parameters encoded using their primary encoding format. - * @throws IOException on encoding errors, or if this parameter object has not - * been initialized. + * Returns the parameters in the default encoding format. The primary encoding + * format is ASN.1 if it exists for the specified type. + * + * @return byte array representing the parameters. */ public final byte[] getEncoded() throws IOException { @@ -312,15 +276,16 @@ public class AlgorithmParameters } /** - * Returns the parameters encoded in the specified scheme. If format is - * <code>null</code>, the primary encoding format for parameters is used. The - * primary encoding format is ASN.1, if an ASN.1 specification for these - * parameters exists. - * - * @param format the name of the encoding format. + * Returns the parameters in the specified encoding format. If + * <code>format</code> is <code>null</code> then the ASN.1 encoding + * format is used if it exists for the specified type. + * + * @param format + * the name of the encoding format to use. * @return the parameters encoded using the specified encoding scheme. - * @throws IOException on encoding errors, or if this parameter object has - * not been initialized. + * @throws IOException + * if an encoding exception occurs, or if this parameter object has + * not been initialized. */ public final byte[] getEncoded(String format) throws IOException { @@ -328,10 +293,9 @@ public class AlgorithmParameters } /** - * Returns a formatted string describing the parameters. - * - * @return a formatted string describing the parameters, or <code>null</code> - * if this parameter object has not been initialized. + * Returns a string representation of the encoded form. + * + * @return a string representation of the encoded form. */ public final String toString() { diff --git a/libjava/classpath/java/security/DigestException.java b/libjava/classpath/java/security/DigestException.java index 6393e0cc834..b4df0c1d582 100644 --- a/libjava/classpath/java/security/DigestException.java +++ b/libjava/classpath/java/security/DigestException.java @@ -1,5 +1,5 @@ /* DigestException.java -- A generic message digest exception - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,4 +67,26 @@ public class DigestException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public DigestException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public DigestException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/GeneralSecurityException.java b/libjava/classpath/java/security/GeneralSecurityException.java index 72453ee8cbf..87e51ce3b50 100644 --- a/libjava/classpath/java/security/GeneralSecurityException.java +++ b/libjava/classpath/java/security/GeneralSecurityException.java @@ -1,5 +1,5 @@ /* GeneralSecurityException.java -- Common superclass of security exceptions - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -72,4 +72,26 @@ public class GeneralSecurityException extends Exception { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public GeneralSecurityException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public GeneralSecurityException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/Identity.java b/libjava/classpath/java/security/Identity.java index 7ef59cfe2de..c9df0a58ffa 100644 --- a/libjava/classpath/java/security/Identity.java +++ b/libjava/classpath/java/security/Identity.java @@ -41,31 +41,27 @@ import java.io.Serializable; import java.util.Vector; /** - * <p>This class represents identities: real-world objects such as people, - * companies or organizations whose identities can be authenticated using their - * public keys. Identities may also be more abstract (or concrete) constructs, - * such as daemon threads or smart cards.</p> - * - * <p>All Identity objects have a <i>name</i> and a <i>public key</i>. Names - * are immutable. <i>Identities</i> may also be <b>scoped</b>. That is, if an - * <i>Identity</i> is specified to have a particular <i>scope</i>, then the - * <i>name</i> and <i>public key</i> of the <i>Identity</i> are unique within - * that <i>scope</i>.</p> - * - * <p>An <i>Identity</i> also has a <i>set of certificates</i> (all certifying - * its own <i>public key</i>). The <i>Principal</i> names specified in these - * certificates need not be the same, only the key.</p> - * - * <p>An <i>Identity</i> can be subclassed, to include postal and email - * addresses, telephone numbers, images of faces and logos, and so on.</p> + * The <code>Identity</code> class is used to represent people and companies + * that can be authenticated using public key encryption. The identities can + * also be abstract objects such as smart cards. + * + * <p><code>Identity</code> objects store a name and public key for each + * identity. The names cannot be changed and the identities can be scoped. Each + * identity (name and public key) within a scope are unique to that scope.</p> + * + * <p>Each identity has a set of ceritificates which all specify the same + * public key, but not necessarily the same name.</p> + * + * <p>The <code>Identity</code> class can be subclassed to allow additional + * information to be attached to it.</p> * * @author Mark Benvenuto * @see IdentityScope * @see Signer * @see Principal - * @deprecated This class is no longer used. Its functionality has been replaced - * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code> - * package, and <code>java.security.Principal</code>. + * @deprecated Replaced by <code>java.security.KeyStore</code>, the + * <code>java.security.cert</code> package, and + * <code>java.security.Principal</code>. */ public abstract class Identity implements Principal, Serializable { @@ -83,12 +79,15 @@ public abstract class Identity implements Principal, Serializable } /** - * Constructs an identity with the specified name and scope. - * - * @param name the identity name. - * @param scope the scope of the identity. - * @throws KeyManagementException if there is already an identity with the - * same name in the scope. + * Constructs a new instance of <code>Identity</code> with the specified + * name and scope. + * + * @param name + * the name to use. + * @param scope + * the scope to use. + * @throws KeyManagementException + * if the identity is already present. */ public Identity(String name, IdentityScope scope) throws KeyManagementException @@ -98,9 +97,11 @@ public abstract class Identity implements Principal, Serializable } /** - * Constructs an identity with the specified name and no scope. - * - * @param name the identity name. + * Constructs a new instance of <code>Identity</code> with the specified + * name and no scope. + * + * @param name + * the name to use. */ public Identity(String name) { @@ -108,30 +109,20 @@ public abstract class Identity implements Principal, Serializable this.scope = null; } - /** - * Returns this identity's name. - * - * @return the name of this identity. - */ + /** @return the name of this identity. */ public final String getName() { return name; } - /** - * Returns this identity's scope. - * - * @return the scope of this identity. - */ + /** @return the scope of this identity. */ public final IdentityScope getScope() { return scope; } /** - * Returns this identity's public key. - * - * @return the public key for this identity. + * @return the public key of this identity. * @see #setPublicKey(java.security.PublicKey) */ public PublicKey getPublicKey() @@ -140,21 +131,17 @@ public abstract class Identity implements Principal, Serializable } /** - * <p>Sets this identity's public key. The old key and all of this identity's - * certificates are removed by this operation.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"setIdentityPublicKey"</code> as its - * argument to see if it's ok to set the public key.</p> - * - * @param key the public key for this identity. - * @throws KeyManagementException if another identity in the identity's scope - * has the same public key, or if another exception occurs. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow setting the public - * key. - * @see #getPublicKey() - * @see SecurityManager#checkSecurityAccess(String) + * Sets the public key for this identity. The old key and all certificates + * are removed. + * + * @param key + * the public key to use. + * @throws KeyManagementException + * if this public key is used by another identity in the current + * scope. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public void setPublicKey(PublicKey key) throws KeyManagementException { @@ -166,18 +153,13 @@ public abstract class Identity implements Principal, Serializable } /** - * <p>Specifies a general information string for this identity.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"setIdentityInfo"</code> as its - * argument to see if it's ok to specify the information string.</p> - * - * @param info the information string. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow setting the - * information string. - * @see #getInfo() - * @see SecurityManager#checkSecurityAccess(String) + * Sets the general information string. + * + * @param info + * the general information string. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public void setInfo(String info) { @@ -189,9 +171,7 @@ public abstract class Identity implements Principal, Serializable } /** - * Returns general information previously specified for this identity. - * - * @return general information about this identity. + * @return the general information string of this identity. * @see #setInfo(String) */ public String getInfo() @@ -200,23 +180,17 @@ public abstract class Identity implements Principal, Serializable } /** - * <p>Adds a certificate for this identity. If the identity has a public key, - * the public key in the certificate must be the same, and if the identity - * does not have a public key, the identity's public key is set to be that - * specified in the certificate.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"addIdentityCertificate"</code> as its - * argument to see if it's ok to add a certificate.</p> - * - * @param certificate the certificate to be added. - * @throws KeyManagementException if the certificate is not valid, if the - * public key in the certificate being added conflicts with this identity's - * public key, or if another exception occurs. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow adding a - * certificate. - * @see SecurityManager#checkSecurityAccess(String) + * Adds a certificate to the list of ceritificates for this identity. The + * public key in this certificate must match the existing public key if it + * exists. + * + * @param certificate + * the certificate to add. + * @throws KeyManagementException + * if the certificate is invalid, or the public key conflicts. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public void addCertificate(Certificate certificate) throws KeyManagementException @@ -235,19 +209,15 @@ public abstract class Identity implements Principal, Serializable } /** - * <p>Removes a certificate from this identity.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"removeIdentityCertificate"</code> as - * its argument to see if it's ok to remove a certificate.</p> - * - * @param certificate the certificate to be removed. - * @throws KeyManagementException if the certificate is missing, or if - * another exception occurs. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow removing a - * certificate. - * @see SecurityManager#checkSecurityAccess(String) + * Removes a certificate from the list of ceritificates for this identity. + * + * @param certificate + * the certificate to remove. + * @throws KeyManagementException + * if the certificate is invalid. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public void removeCertificate(Certificate certificate) throws KeyManagementException @@ -262,11 +232,7 @@ public abstract class Identity implements Principal, Serializable certificates.removeElement(certificate); } - /** - * Returns a copy of all the certificates for this identity. - * - * @return a copy of all the certificates for this identity. - */ + /** @return an array of {@link Certificate}s for this identity. */ public Certificate[] certificates() { Certificate[] certs = new Certificate[certificates.size()]; @@ -278,17 +244,13 @@ public abstract class Identity implements Principal, Serializable } /** - * Tests for equality between the specified object and this identity. This - * first tests to see if the entities actually refer to the same object, in - * which case it returns <code>true</code>. Next, it checks to see if the - * entities have the same <i>name</i> and the same <i>scope</i>. If they do, - * the method returns <code>true</code>. Otherwise, it calls - * <code>identityEquals()</code>, which subclasses should override. - * - * @param identity the object to test for equality with this identity. - * @return <code>true</code> if the objects are considered equal, <code>false - * </code>otherwise. - * @see #identityEquals(Identity) + * Checks for equality between this Identity and a specified object. It first + * checks if they are the same object, then if the name and scope match and + * returns <code>true</code> if successful. If these tests fail, the + * {@link #identityEquals(Identity)} method is called. + * + * @return <code>true</code> if they are equal, <code>false</code> + * otherwise. */ public final boolean equals(Object identity) { @@ -307,15 +269,12 @@ public abstract class Identity implements Principal, Serializable } /** - * Tests for equality between the specified <code>identity</code> and this - * <i>identity</i>. This method should be overriden by subclasses to test for - * equality. The default behavior is to return <code>true</code> if the names - * and public keys are equal. - * - * @param identity the identity to test for equality with this identity. - * @return <code>true</code> if the identities are considered equal, - * <code>false</code> otherwise. - * @see #equals(Object) + * Checks for equality between this Identity and a specified object. A + * subclass should override this method. The default behavior is to return + * <code>true</code> if the public key and names match. + * + * @return <code>true</code> if they are equal, <code>false</code> + * otherwise. */ protected boolean identityEquals(Identity identity) { @@ -324,19 +283,12 @@ public abstract class Identity implements Principal, Serializable } /** - * <p>Returns a short string describing this identity, telling its name and - * its scope (if any).</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"printIdentity"</code> as its argument - * to see if it's ok to return the string.</p> - * - * @return information about this identity, such as its name and the name of - * its scope (if any). - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow returning a string - * describing this identity. - * @see SecurityManager#checkSecurityAccess(String) + * Returns a string representation of this Identity. + * + * @return a string representation of this Identity. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public String toString() { @@ -349,23 +301,14 @@ public abstract class Identity implements Principal, Serializable } /** - * <p>Returns a string representation of this identity, with optionally more - * details than that provided by the <code>toString()</code> method without - * any arguments.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"printIdentity"</code> as its argument - * to see if it's ok to return the string.</p> - * - * @param detailed whether or not to provide detailed information. - * @return information about this identity. If detailed is <code>true</code>, - * then this method returns more information than that provided by the - * <code>toString()</code> method without any arguments. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow returning a string - * describing this identity. - * @see #toString() - * @see SecurityManager#checkSecurityAccess(String) + * Returns a detailed string representation of this Identity. + * + * @param detailed + * indicates whether or detailed information is desired. + * @return a string representation of this Identity. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public String toString(boolean detailed) { @@ -385,11 +328,7 @@ public abstract class Identity implements Principal, Serializable } } - /** - * Returns a hashcode for this identity. - * - * @return a hashcode for this identity. - */ + /** @return a hashcode of this identity. */ public int hashCode() { int ret = name.hashCode(); diff --git a/libjava/classpath/java/security/IdentityScope.java b/libjava/classpath/java/security/IdentityScope.java index 34dd011e280..d1ea1f29500 100644 --- a/libjava/classpath/java/security/IdentityScope.java +++ b/libjava/classpath/java/security/IdentityScope.java @@ -40,52 +40,42 @@ package java.security; import java.util.Enumeration; /** - * <p>This class represents a scope for identities. It is an Identity itself, - * and therefore has a name and can have a scope. It can also optionally have a - * public key and associated certificates.</p> - * - * <p>An <code>IdentityScope</code> can contain {@link Identity} objects of all - * kinds, including {@link Signer}s. All types of <code>Identity</code> objects - * can be retrieved, added, and removed using the same methods. Note that it is - * possible, and in fact expected, that different types of identity scopes will - * apply different policies for their various operations on the various types of + * <code>IdentityScope</code> represents a scope of an identity. + * <code>IdentityScope</code> is also an {@link Identity} and can have a name + * and scope along with the other qualitites identities possess. + * + * <p>An <code>IdentityScope</code> contains other {@link Identity} objects. + * All {@link Identity} objects are manipulated in the scope the same way. The + * scope is supposed to apply different scope to different type of * Identities.</p> - * - * <p>There is a one-to-one mapping between keys and identities, and there can - * only be one copy of one key per scope. For example, suppose Acme Software, - * Inc is a software publisher known to a user. Suppose it is an <i>Identity</i>, - * that is, it has a public key, and a set of associated certificates. It is - * named in the scope using the name "Acme Software". No other named <i>Identity - * </i> in the scope has the same public key. Of course, none has the same name - * as well.</p> - * + * + * <p>No identity within the same scope can have the same public key.</p> + * * @author Mark Benvenuto * @see Identity * @see Signer * @see Principal * @see Key - * @deprecated This class is no longer used. Its functionality has been replaced - * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code> - * package, and <code>java.security.Principal</code>. + * @deprecated Use java.security.KeyStore, the java.security.cert package, and + * java.security.Principal. */ public abstract class IdentityScope extends Identity { private static final long serialVersionUID = -2337346281189773310L; private static IdentityScope systemScope; - /** - * This constructor is used for serialization only and should not be used by - * subclasses. - */ + /** Constructor for serialization purposes. */ protected IdentityScope() { super(); } /** - * Constructs a new identity scope with the specified name. - * - * @param name the scope name. + * Constructs a new instance of <code>IdentityScope</code> with the + * specified name and no scope. + * + * @param name + * the name to use. */ public IdentityScope(String name) { @@ -93,12 +83,15 @@ public abstract class IdentityScope extends Identity } /** - * Constructs a new identity scope with the specified name and scope. - * - * @param name the scope name. - * @param scope the scope for the new identity scope. - * @throws KeyManagementException if there is already an identity with the - * same name in the scope. + * Constructs a new instance of <code>IdentityScope</code> with the + * specified name and {@link IdentityScope}. + * + * @param name + * the name to use. + * @param scope + * the scope to use. + * @throws KeyManagementException + * if the identity scope is already present. */ public IdentityScope(String name, IdentityScope scope) throws KeyManagementException @@ -107,10 +100,9 @@ public abstract class IdentityScope extends Identity } /** - * Returns the system's identity scope. - * - * @return the system's identity scope. - * @see #setSystemScope(IdentityScope) + * Returns the system's Scope. + * + * @return the system's Scope. */ public static IdentityScope getSystemScope() { @@ -123,18 +115,13 @@ public abstract class IdentityScope extends Identity } /** - * Sets the system's identity scope. - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"setSystemScope"</code> as its argument - * to see if it's ok to set the identity scope.</p> - * - * @param scope the scope to set. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow setting the - * identity scope. - * @see #getSystemScope() - * @see SecurityManager#checkSecurityAccess(String) + * Sets the scope of the system. + * + * @param scope + * the new system scope. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ protected static void setSystemScope(IdentityScope scope) { @@ -146,29 +133,30 @@ public abstract class IdentityScope extends Identity } /** - * Returns the number of identities within this identity scope. - * - * @return the number of identities within this identity scope. + * Returns the number of entries within this <code>IdentityScope</code>. + * + * @return the number of entries within this <code>IdentityScope</code>. */ public abstract int size(); /** - * Returns the identity in this scope with the specified name (if any). - * - * @param name the name of the identity to be retrieved. - * @return the identity named name, or <code>null</code> if there are no - * identities named name in this scope. + * Returns the specified {@link Identity}, by name, within this scope. + * + * @param name + * name of {@link Identity} to get. + * @return an {@link Identity} representing the name or <code>null</code> if + * it cannot be found. */ public abstract Identity getIdentity(String name); /** - * Retrieves the identity whose name is the same as that of the specified - * principal. (Note: <code>Identity</code> implements <code>Principal</code>.) - * - * @param principal the principal corresponding to the identity to be - * retrieved. - * @return the identity whose name is the same as that of the principal, or - * <code>null</code> if there are no identities of the same name in this scope. + * Returns the specified {@link Identity}, by {@link Principal}, within this + * scope. + * + * @param principal + * the {@link Principal} to use. + * @return an identity representing the {@link Principal} or <code>null</code> + * if it cannot be found. */ public Identity getIdentity(Principal principal) { @@ -176,48 +164,50 @@ public abstract class IdentityScope extends Identity } /** - * Retrieves the identity with the specified public key. - * - * @param key the public key for the identity to be returned. - * @return the identity with the given key, or <code>null</code> if there are - * no identities in this scope with that key. + * Returns the specified {@link Identity}, by public key, within this scope. + * + * @param key + * the {@link PublicKey} to use. + * @return an identity representing the public key or <code>null</code> if + * it cannot be found. */ public abstract Identity getIdentity(PublicKey key); /** - * Adds an identity to this identity scope. - * - * @param identity the identity to be added. - * @throws KeyManagementException if the identity is not valid, a name - * conflict occurs, another identity has the same public key as the identity - * being added, or another exception occurs. + * Adds an identity to his scope. + * + * @param identity + * the {@link Identity} to add. + * @throws KeyManagementException + * if it is an invalid identity, an identity with the same key + * exists, or if another error occurs. */ public abstract void addIdentity(Identity identity) throws KeyManagementException; /** - * Removes an identity from this identity scope. - * - * @param identity the identity to be removed. - * @throws KeyManagementException if the identity is missing, or another - * exception occurs. + * Removes an identity in this scope. + * + * @param identity + * the {@link Identity} to remove. + * @throws KeyManagementException + * if it is a missing identity, or if another error occurs. */ public abstract void removeIdentity(Identity identity) throws KeyManagementException; /** - * Returns an enumeration of all identities in this identity scope. - * - * @return an enumeration of all identities in this identity scope. + * Returns an {@link Enumeration} of identities in this scope. + * + * @return an {@link Enumeration} of the identities in this scope. */ public abstract Enumeration identities(); /** - * Returns a string representation of this identity scope, including its name, - * its scope name, and the number of identities in this identity scope. - * - * @return a string representation of this identity scope. - * @see SecurityManager#checkSecurityAccess(String) + * Returns a string representing this instance. It includes the name, the + * scope name, and number of identities. + * + * @return a string representation of this instance. */ public String toString() { diff --git a/libjava/classpath/java/security/InvalidAlgorithmParameterException.java b/libjava/classpath/java/security/InvalidAlgorithmParameterException.java index 9b726199521..aa77937fb3f 100644 --- a/libjava/classpath/java/security/InvalidAlgorithmParameterException.java +++ b/libjava/classpath/java/security/InvalidAlgorithmParameterException.java @@ -1,6 +1,6 @@ /* InvalidAlgorithmParameterException.java -- an invalid parameter to a security algorithm - Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -70,4 +70,26 @@ public class InvalidAlgorithmParameterException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public InvalidAlgorithmParameterException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public InvalidAlgorithmParameterException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/InvalidKeyException.java b/libjava/classpath/java/security/InvalidKeyException.java index cd5845a6181..39aa3df4355 100644 --- a/libjava/classpath/java/security/InvalidKeyException.java +++ b/libjava/classpath/java/security/InvalidKeyException.java @@ -1,5 +1,5 @@ /* InvalidKeyException -- thrown for an invalid key - Copyright (C) 2000, 2002 Free Software Foundation + Copyright (C) 2000, 2002, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -66,4 +66,26 @@ public class InvalidKeyException extends KeyException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public InvalidKeyException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public InvalidKeyException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/KeyException.java b/libjava/classpath/java/security/KeyException.java index feaf0249a95..66f1feb64a6 100644 --- a/libjava/classpath/java/security/KeyException.java +++ b/libjava/classpath/java/security/KeyException.java @@ -1,5 +1,5 @@ /* KeyException.java -- Thrown when there is a problem with a key - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -69,4 +69,26 @@ public class KeyException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public KeyException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public KeyException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/KeyFactory.java b/libjava/classpath/java/security/KeyFactory.java index 64ce841fae8..edb2a87dafb 100644 --- a/libjava/classpath/java/security/KeyFactory.java +++ b/libjava/classpath/java/security/KeyFactory.java @@ -44,40 +44,18 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; /** - * <p>Key factories are used to convert keys (opaque cryptographic keys of type + * Key factories are used to convert keys (opaque cryptographic keys of type * {@link Key}) into key specifications (transparent representations of the - * underlying key material), and vice versa.</p> - * - * <p>Key factories are bi-directional. That is, they allow you to build an - * opaque key object from a given key specification (key material), or to - * retrieve the underlying key material of a key object in a suitable format.</p> - * - * <p>Multiple compatible key specifications may exist for the same key. For - * example, a <i>DSA</i> public key may be specified using {@link - * java.security.spec.DSAPublicKeySpec} or {@link - * java.security.spec.X509EncodedKeySpec}. A key factory can be used to - * translate between compatible key specifications.</p> - * - * <p>The following is an example of how to use a key factory in order to - * instantiate a <i>DSA</i> public key from its encoding. Assume Alice has - * received a digital signature from Bob. Bob also sent her his public key (in - * encoded format) to verify his signature. Alice then performs the following - * actions: - * - * <pre> - * X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey); - * KeyFactory keyFactory = KeyFactory.getInstance("DSA"); - * PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec); - * Signature sig = Signature.getInstance("DSA"); - * sig.initVerify(bobPubKey); - * sig.update(data); - * sig.verify(signature); - * </pre> + * underlying key material). + * + * <p>Key factories are bi-directional. They allow a key class to be converted + * into a key specification (key material) and back again. For example DSA + * public keys can be specified as <code>DSAPublicKeySpec</code> or + * <code>X509EncodedKeySpec</code>. A key factory translates these key + * specifications.</p> * * @since 1.2 * @see Key - * @see PublicKey - * @see PrivateKey * @see KeySpec * @see java.security.spec.DSAPublicKeySpec * @see java.security.spec.X509EncodedKeySpec @@ -93,12 +71,15 @@ public class KeyFactory private String algorithm; /** - * Creates a <code>KeyFactory</code> object. - * - * @param keyFacSpi the delegate. - * @param provider the provider. - * @param algorithm the name of the algorithm to associate with this - * <code>KeyFactory</code>. + * Constructs a new instance of <code>KeyFactory</code> with the specified + * parameters. + * + * @param keyFacSpi + * the key factory to use. + * @param provider + * the provider to use. + * @param algorithm + * the name of the key algorithm to use. */ protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider, String algorithm) @@ -109,19 +90,14 @@ public class KeyFactory } /** - * Generates a <code>KeyFactory</code> object that implements the specified - * algorithm. If the default provider package provides an implementation of - * the requested algorithm, an instance of <code>KeyFactory</code> containing - * that implementation is returned. If the algorithm is not available in the - * default package, other packages are searched. - * - * @param algorithm the name of the requested key algorithm. See Appendix A - * in the Java Cryptography Architecture API Specification & Reference - * for information about standard algorithm names. - * @return a <code>KeyFactory</code> object for the specified algorithm. - * @throws NoSuchAlgorithmException if the requested algorithm is not - * available in the default provider package or any of the other provider - * packages that were searched. + * Returns a new instance of <code>KeyFactory</code> representing the + * specified key factory. + * + * @param algorithm + * the name of algorithm to use. + * @return a new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by any provider. */ public static KeyFactory getInstance(String algorithm) throws NoSuchAlgorithmException @@ -141,19 +117,21 @@ public class KeyFactory } /** - * Generates a <code>KeyFactory</code> object for the specified algorithm - * from the specified provider. - * - * @param algorithm the name of the requested key algorithm. See Appendix A - * in the Java Cryptography Architecture API Specification & Reference - * for information about standard algorithm names. - * @param provider the name of the provider. - * @return a <code>KeyFactory</code> object for the specified algorithm. - * @throws NoSuchAlgorithmException if the algorithm is not available from - * the specified provider. - * @throws NoSuchProviderException if the provider has not been configured. - * @throws IllegalArgumentException if the provider name is null or empty. - * @see Provider + * Returns a new instance of <code>KeyFactory</code> representing the + * specified key factory from the specified provider. + * + * @param algorithm + * the name of algorithm to use. + * @param provider + * the name of the provider to use. + * @return a new instance repesenting the desired algorithm. + * @throws IllegalArgumentException + * if <code>provider</code> is <code>null</code> or is an empty + * string. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the named provider. + * @throws NoSuchProviderException + * if the named provider was not found. */ public static KeyFactory getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException @@ -169,19 +147,18 @@ public class KeyFactory } /** - * Generates a <code>KeyFactory</code> object for the specified algorithm from - * the specified provider. Note: the <code>provider</code> doesn't have to be - * registered. - * - * @param algorithm the name of the requested key algorithm. See Appendix A - * in the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @param provider the provider. - * @return a <code>KeyFactory</code> object for the specified algorithm. - * @throws NoSuchAlgorithmException if the algorithm is not available from - * the specified provider. - * @throws IllegalArgumentException if the <code>provider</code> is - * <code>null</code>. + * Returns a new instance of <code>KeyFactory</code> representing the + * specified key factory from the designated {@link Provider}. + * + * @param algorithm + * the name of algorithm to use. + * @param provider + * the {@link Provider} to use. + * @return a new instance repesenting the desired algorithm. + * @throws IllegalArgumentException + * if <code>provider</code> is <code>null</code>. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by {@link Provider}. * @since 1.4 * @see Provider */ @@ -208,9 +185,9 @@ public class KeyFactory } /** - * Returns the provider of this key factory object. - * - * @return the provider of this key factory object. + * Returns the {@link Provider} of this instance. + * + * @return the {@link Provider} of this instance. */ public final Provider getProvider() { @@ -218,10 +195,9 @@ public class KeyFactory } /** - * Gets the name of the algorithm associated with this <code>KeyFactory</code>. - * - * @return the name of the algorithm associated with this - * <code>KeyFactory</code>. + * Returns the name of the algorithm used. + * + * @return the name of the algorithm used. */ public final String getAlgorithm() { @@ -229,13 +205,13 @@ public class KeyFactory } /** - * Generates a public key object from the provided key specification (key - * material). - * - * @param keySpec the specification (key material) of the public key. + * Generates a public key from the provided key specification. + * + * @param keySpec + * the key specification. * @return the public key. - * @throws InvalidKeySpecException if the given key specification is - * inappropriate for this key factory to produce a public key. + * @throws InvalidKeySpecException + * if the key specification is invalid. */ public final PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException @@ -244,13 +220,13 @@ public class KeyFactory } /** - * Generates a private key object from the provided key specification (key - * material). - * - * @param keySpec the specification (key material) of the private key. + * Generates a private key from the provided key specification. + * + * @param keySpec + * the key specification. * @return the private key. - * @throws InvalidKeySpecException if the given key specification is - * inappropriate for this key factory to produce a private key. + * @throws InvalidKeySpecException + * if the key specification is invalid. */ public final PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException @@ -259,21 +235,18 @@ public class KeyFactory } /** - * Returns a specification (key material) of the given key object. - * <code>keySpec</code> identifies the specification class in which the key - * material should be returned. It could, for example, be - * <code>DSAPublicKeySpec.class</code>, to indicate that the key material - * should be returned in an instance of the {@link - * java.security.spec.DSAPublicKeySpec} class. - * - * @param key the key. - * @param keySpec the specification class in which the key material should be - * returned. - * @return the underlying key specification (key material) in an instance of - * the requested specification class. - * @throws InvalidKeySpecException if the requested key specification is - * inappropriate for the given key, or the given key cannot be processed - * (e.g., the given key has an unrecognized algorithm or format). + * Returns a key specification for the given key. <code>keySpec</code> + * identifies the specification class to return the key material in. + * + * @param key + * the key to use. + * @param keySpec + * the specification class to use. + * @return the key specification in an instance of the requested specification + * class. + * @throws InvalidKeySpecException + * the requested key specification is inappropriate for this key or + * the key is unrecognized. */ public final KeySpec getKeySpec(Key key, Class keySpec) throws InvalidKeySpecException @@ -282,13 +255,14 @@ public class KeyFactory } /** - * Translates a key object, whose provider may be unknown or potentially - * untrusted, into a corresponding key object of this key factory. - * - * @param key the key whose provider is unknown or untrusted. + * Translates the key from an unknown or untrusted provider into a key from + * this key factory. + * + * @param key + * the key to translate from. * @return the translated key. - * @throws InvalidKeyException if the given key cannot be processed by this - * key factory. + * @throws InvalidKeyException + * if the key cannot be processed by this key factory. */ public final Key translateKey(Key key) throws InvalidKeyException { diff --git a/libjava/classpath/java/security/KeyManagementException.java b/libjava/classpath/java/security/KeyManagementException.java index 694b4c242b6..f39fe312efa 100644 --- a/libjava/classpath/java/security/KeyManagementException.java +++ b/libjava/classpath/java/security/KeyManagementException.java @@ -1,5 +1,5 @@ /* KeyManagementException.java -- an exception in key management - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -68,4 +68,26 @@ public class KeyManagementException extends KeyException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public KeyManagementException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public KeyManagementException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/KeyPairGenerator.java b/libjava/classpath/java/security/KeyPairGenerator.java index a6e010be2bc..357d7a75f2f 100644 --- a/libjava/classpath/java/security/KeyPairGenerator.java +++ b/libjava/classpath/java/security/KeyPairGenerator.java @@ -43,72 +43,14 @@ import gnu.java.security.Engine; import java.security.spec.AlgorithmParameterSpec; /** - * <p>The <code>KeyPairGenerator</code> class is used to generate pairs of - * public and private keys. Key pair generators are constructed using the - * <code>getInstance()</code> factory methods (static methods that return - * instances of a given class).</p> + * <code>KeyPairGenerator</code> is a class used to generate key-pairs for a + * security algorithm. + * + * <p>The <code>KeyPairGenerator</code> is created with the + * <code>getInstance()</code> Factory methods. It is used to generate a pair of + * public and private keys for a specific algorithm and associate this key-pair + * with the algorithm parameters it was initialized with.</p> * - * <p>A Key pair generator for a particular algorithm creates a public/private - * key pair that can be used with this algorithm. It also associates - * algorithm-specific parameters with each of the generated keys.</p> - * - * <p>There are two ways to generate a key pair: in an algorithm-independent - * manner, and in an algorithm-specific manner. The only difference between the - * two is the initialization of the object:</p> - * - * <ul> - * <li><b>Algorithm-Independent Initialization</b><br/> - * All key pair generators share the concepts of a <i>keysize</i> and a - * <i>source of randomness</i>. The <i>keysize</i> is interpreted differently - * for different algorithms (e.g., in the case of the <i>DSA</i> algorithm, - * the <i>keysize</i> corresponds to the length of the modulus). There is an - * <code>initialize()</code> method in this <code>KeyPairGenerator</code> - * class that takes these two universally shared types of arguments. There - * is also one that takes just a <i>keysize</i> argument, and uses the - * {@link SecureRandom} implementation of the highest-priority installed - * provider as the <i>source of randomness</i>. (If none of the installed - * providers supply an implementation of {@link SecureRandom}, a - * system-provided source of randomness is used.) - * - * <p>Since no other parameters are specified when you call the above - * algorithm-independent initialize methods, it is up to the provider what - * to do about the algorithm-specific parameters (if any) to be associated - * with each of the keys.</p> - * - * <p>If the algorithm is the <i>DSA</i> algorithm, and the <i>keysize</i> - * (modulus size) is <code>512</code>, <code>768</code>, or <code>1024</code>, - * then the <b>GNU</b> provider uses a set of precomputed values for the - * <code>p</code>, <code>q</code>, and <code>g</code> parameters. If the - * <i>modulus size</i> is not one of the above values, the <b>GNU</b> - * provider creates a new set of parameters. Other providers might have - * precomputed parameter sets for more than just the three modulus sizes - * mentioned above. Still others might not have a list of precomputed - * parameters at all and instead always create new parameter sets.</p></li> - * <li><b>Algorithm-Specific Initialization</b><br/> - * For situations where a set of algorithm-specific parameters already - * exists (e.g., so-called <i>community parameters</i> in <i>DSA</i>), there - * are two initialize methods that have an {@link AlgorithmParameterSpec} - * argument. One also has a {@link SecureRandom} argument, while the the - * other uses the {@link SecureRandom} implementation of the highest-priority - * installed provider as the source of randomness. (If none of the installed - * providers supply an implementation of {@link SecureRandom}, a - * system-provided source of randomness is used.)</li> - * </ul> - * - * <p>In case the client does not explicitly initialize the - * <code>KeyPairGenerator</code> (via a call to an initialize method), each - * provider must supply (and document) a default initialization. For example, - * the <b>GNU</b> provider uses a default modulus size (keysize) of - * <code>1024</code> bits.</p> - * - * <p>Note that this class is abstract and extends from {@link - * KeyPairGeneratorSpi} for historical reasons. Application developers should - * only take notice of the methods defined in this <code>KeyPairGenerator</code> - * class; all the methods in the superclass are intended for cryptographic - * service providers who wish to supply their own implementations of key pair - * generators.</p> - * - * @see Signature * @see KeyPair * @see AlgorithmParameterSpec * @author Mark Benvenuto @@ -123,13 +65,10 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi private String algorithm; /** - * Creates a <code>KeyPairGenerator</code> object for the specified - * algorithm. - * - * @param algorithm the standard string name of the algorithm. - * See Appendix A in the Java Cryptography Architecture API - * Specification & Reference for information about standard - * algorithm names. + * Constructs a new instance of <code>KeyPairGenerator</code>. + * + * @param algorithm + * the algorithm to use. */ protected KeyPairGenerator(String algorithm) { @@ -138,11 +77,9 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * Returns the standard name of the algorithm for this key pair generator. - * See Appendix A in the Java Cryptography Architecture API Specification - * & Reference for information about standard algorithm names. - * - * @return the standard string name of the algorithm. + * Returns the name of the algorithm used. + * + * @return the name of the algorithm used. */ public String getAlgorithm() { @@ -150,19 +87,14 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * Generates a <code>KeyPairGenerator</code> object that implements the - * specified digest algorithm. If the default provider package provides an - * implementation of the requested digest algorithm, an instance of - * <code>KeyPairGenerator</code> containing that implementation is returned. - * If the algorithm is not available in the default package, other packages - * are searched. - * - * @param algorithm the standard string name of the algorithm. See Appendix A - * in the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @return the new <code>KeyPairGenerator</code> object. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * environment. + * Returns a new instance of <code>KeyPairGenerator</code> which generates + * key-pairs for the specified algorithm. + * + * @param algorithm + * the name of the algorithm to use. + * @return a new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by any provider. */ public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException @@ -184,22 +116,18 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * Generates a <code>KeyPairGenerator</code> object implementing the - * specified algorithm, as supplied from the specified provider, if - * such an algorithm is available from the provider. - * - * @param algorithm the standard string name of the algorithm. See - * Appendix A in the Java Cryptography Architecture API Specification - * & Reference for information about standard algorithm names. - * @param provider the string name of the provider. - * @return the new <code>KeyPairGenerator</code> object. - * @throws NoSuchAlgorithmException if the algorithm is not available - * from the provider. - * @throws NoSuchProviderException if the provider is not available in the - * environment. - * @throws IllegalArgumentException if the provider name is <code>null</code> - * or empty. - * @see Provider + * Returns a new instance of <code>KeyPairGenerator</code> which generates + * key-pairs for the specified algorithm from a named provider. + * + * @param algorithm + * the name of the algorithm to use. + * @param provider + * the name of a {@link Provider} to use. + * @return a new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the named provider. + * @throws NoSuchProviderException + * if the named provider was not found. */ public static KeyPairGenerator getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException @@ -212,20 +140,18 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * Generates a <code>KeyPairGenerator</code> object implementing the specified - * algorithm, as supplied from the specified provider, if such an algorithm is - * available from the provider. Note: the provider doesn't have to be - * registered. - * - * @param algorithm the standard string name of the algorithm. See Appendix A - * in the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @param provider the provider. - * @return the new <code>KeyPairGenerator</code> object. - * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not - * available from the <code>provider</code>. - * @throws IllegalArgumentException if the <code>provider</code> is - * <code>null</code>. + * Returns a new instance of <code>KeyPairGenerator</code> which generates + * key-pairs for the specified algorithm from a designated {@link Provider}. + * + * @param algorithm + * the name of the algorithm to use. + * @param provider + * the {@link Provider} to use. + * @return a new insatnce repesenting the desired algorithm. + * @throws IllegalArgumentException + * if <code>provider</code> is <code>null</code>. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the {@link Provider}. * @since 1.4 * @see Provider */ @@ -247,23 +173,22 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } KeyPairGenerator result = null; - if (o instanceof KeyPairGeneratorSpi) - { - result = new DummyKeyPairGenerator((KeyPairGeneratorSpi) o, algorithm); - } - else if (o instanceof KeyPairGenerator) + if (o instanceof KeyPairGenerator) { result = (KeyPairGenerator) o; result.algorithm = algorithm; } + else if (o instanceof KeyPairGeneratorSpi) + result = new DummyKeyPairGenerator((KeyPairGeneratorSpi) o, algorithm); + result.provider = provider; return result; } /** - * Returns the provider of this key pair generator object. - * - * @return the provider of this key pair generator object. + * Returns the {@link Provider} of this instance. + * + * @return the {@link Provider} of this instance. */ public final Provider getProvider() { @@ -271,16 +196,11 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * Initializes the key pair generator for a certain keysize using a default - * parameter set and the {@link SecureRandom} implementation of the - * highest-priority installed provider as the source of randomness. (If none - * of the installed providers supply an implementation of {@link SecureRandom}, - * a system-provided source of randomness is used.) - * - * @param keysize the keysize. This is an algorithm-specific metric, such as - * modulus length, specified in number of bits. - * @throws InvalidParameterException if the keysize is not supported by this - * <code>KeyPairGenerator</code> object. + * Initializes this instance for the specified key size. Since no source of + * randomness is specified, a default one will be used. + * + * @param keysize + * the size of keys to use. */ public void initialize(int keysize) { @@ -288,14 +208,13 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * Initializes the key pair generator for a certain keysize with the given - * source of randomness (and a default parameter set). - * - * @param keysize the keysize. This is an algorithm-specific metric, such as - * modulus length, specified in number of bits. - * @param random the source of randomness. - * @throws InvalidParameterException if the <code>keysize</code> is not - * supported by this <code>KeyPairGenerator</code> object. + * Initializes this instance for the specified key size and + * {@link SecureRandom}. + * + * @param keysize + * the size of keys to use. + * @param random + * the {@link SecureRandom} to use. * @since 1.2 */ public void initialize(int keysize, SecureRandom random) @@ -303,24 +222,14 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * <p>Initializes the key pair generator using the specified parameter set and - * the {@link SecureRandom} implementation of the highest-priority installed - * provider as the source of randomness. (If none of the installed providers - * supply an implementation of {@link SecureRandom}, a system-provided source - * of randomness is used.)</p> - * - * <p>This concrete method has been added to this previously-defined abstract - * class. This method calls the - * {@link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)} - * initialize method, passing it <code>params</code> and a source of - * randomness (obtained from the highest-priority installed provider or - * system-provided if none of the installed providers supply one). That - * initialize method always throws an {@link UnsupportedOperationException} - * if it is not overridden by the provider.</p> - * - * @param params the parameter set used to generate the keys. - * @throws InvalidAlgorithmParameterException if the given parameters are - * inappropriate for this key pair generator. + * Initializes this instance with the specified + * {@link AlgorithmParameterSpec}. Since no source of randomness is specified, + * a default one will be used. + * + * @param params + * the {@link AlgorithmParameterSpec} to use. + * @throws InvalidAlgorithmParameterException + * if the designated specifications are invalid. * @since 1.2 */ public void initialize(AlgorithmParameterSpec params) @@ -330,20 +239,15 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * <p>Initializes the key pair generator with the given parameter set and - * source of randomness.</p> - * - * <p>This concrete method has been added to this previously-defined abstract - * class. This method calls the - * {@link KeyPairGeneratorSpi#initialize(AlgorithmParameterSpec, SecureRandom)} - * initialize method, passing it <code>params</code> and <code>random</code>. - * That initialize method always throws an {@link UnsupportedOperationException} - * if it is not overridden by the provider.</p> - * - * @param params the parameter set used to generate the keys. - * @param random the source of randomness. - * @throws InvalidAlgorithmParameterException if the given parameters are - * inappropriate for this key pair generator. + * Initializes this instance with the specified {@link AlgorithmParameterSpec} + * and {@link SecureRandom}. + * + * @param params + * the {@link AlgorithmParameterSpec} to use. + * @param random + * the {@link SecureRandom} to use. + * @throws InvalidAlgorithmParameterException + * if the designated specifications are invalid. * @since 1.2 */ public void initialize(AlgorithmParameterSpec params, SecureRandom random) @@ -353,17 +257,12 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * <p>Generates a key pair.</p> - * - * <p>If this <code>KeyPairGenerator</code> has not been initialized - * explicitly, provider-specific defaults will be used for the size and other - * (algorithm-specific) values of the generated keys.</p> - * - * <p>This will generate a new key pair every time it is called.</p> - * - * <p>This method is functionally equivalent to {@link #generateKeyPair()}.</p> - * - * @return the generated key pair. + * Generates a new "DSA" {@link KeyPair} from the "GNU" security provider. + * + * <p>This method generates a unique key-pair each time it is called.</p> + * + * @return a new unique {@link KeyPair}. + * @see #generateKeyPair() * @since 1.2 */ public final KeyPair genKeyPair() @@ -381,17 +280,12 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi } /** - * <p>Generates a key pair.</p> - * - * <p>If this <code>KeyPairGenerator</code> has not been initialized - * explicitly, provider-specific defaults will be used for the size and other - * (algorithm-specific) values of the generated keys.</p> - * - * <p>This will generate a new key pair every time it is called.</p> - * - * <p>This method is functionally equivalent to {@link #genKeyPair()}.</p> - * - * @return the generated key pair. + * Generates a new "DSA" {@link KeyPair} from the "GNU" security provider. + * + * <p>This method generates a unique key pair each time it is called.</p> + * + * @return a new unique {@link KeyPair}. + * @see #genKeyPair() */ public KeyPair generateKeyPair() { diff --git a/libjava/classpath/java/security/KeyStoreException.java b/libjava/classpath/java/security/KeyStoreException.java index 9a0a5354d2c..62f906e6e36 100644 --- a/libjava/classpath/java/security/KeyStoreException.java +++ b/libjava/classpath/java/security/KeyStoreException.java @@ -1,5 +1,5 @@ /* KeyStoreException.java -- Indicates a problem with the key store - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,4 +67,26 @@ public class KeyStoreException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public KeyStoreException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public KeyStoreException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/MessageDigest.java b/libjava/classpath/java/security/MessageDigest.java index 8a6af645be1..b817759f547 100644 --- a/libjava/classpath/java/security/MessageDigest.java +++ b/libjava/classpath/java/security/MessageDigest.java @@ -40,54 +40,10 @@ package java.security; import gnu.java.security.Engine; /** - * <p>This <code>MessageDigest</code> class provides applications the - * functionality of a message digest algorithm, such as <i>MD5</i> or <i>SHA</i>. * Message digests are secure one-way hash functions that take arbitrary-sized - * data and output a fixed-length hash value.</p> - * - * <p>A <code>MessageDigest</code> object starts out initialized. The data is - * processed through it using the <code>update()</code> methods. At any point - * <code>reset()</code> can be called to reset the digest. Once all the data to - * be updated has been updated, one of the <code>digest()</code> methods should - * be called to complete the hash computation.</p> - * - * <p>The <code>digest()</code> method can be called <b>once</b> for a given - * number of updates. After <code>digest()</code> has been called, the - * <code>MessageDigest</code> object is <b>reset</b> to its initialized state. - * </p> - * - * <p>Implementations are free to implement the {@link Cloneable} interface. - * Client applications can test cloneability by attempting cloning and catching - * the {@link CloneNotSupportedException}: - * - * <pre> - * MessageDigest md = MessageDigest.getInstance("SHA"); - * try - * { - * md.update(toChapter1); - * MessageDigest tc1 = md.clone(); - * byte[] toChapter1Digest = tc1.digest(); - * md.update(toChapter2); - * // ... - * } - * catch (CloneNotSupportedException x) - * { - * throw new DigestException("couldn't make digest of partial content"); - * } - * </pre> - * - * <p>Note that if a given implementation is not cloneable, it is still possible - * to compute intermediate digests by instantiating several instances, if the - * number of digests is known in advance.</p> - * - * <p>Note that this class is abstract and extends from {@link MessageDigestSpi} - * for historical reasons. Application developers should only take notice of the - * methods defined in this <code>MessageDigest</code> class; all the methods in - * the superclass are intended for cryptographic service providers who wish to - * supply their own implementations of message digest algorithms.</p> + * data and output a fixed-length hash value. * * @see MessageDigestSpi - * @see Provider * @since JDK 1.1 */ public abstract class MessageDigest extends MessageDigestSpi @@ -100,12 +56,11 @@ public abstract class MessageDigest extends MessageDigestSpi private byte[] lastDigest; /** - * Creates a message digest with the specified algorithm name. - * - * @param algorithm the standard name of the digest algorithm. - * See Appendix A in the Java Cryptography Architecture API - * Specification & Reference for information about standard - * algorithm names. + * Constructs a new instance of <code>MessageDigest</code> representing the + * specified algorithm. + * + * @param algorithm + * the name of the digest algorithm to use. */ protected MessageDigest(String algorithm) { @@ -114,19 +69,14 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Generates a <code>MessageDigest</code> object that implements the specified - * digest algorithm. If the default provider package provides an - * implementation of the requested digest algorithm, an instance of - * <code>MessageDigest</code> containing that implementation is returned. If - * the algorithm is not available in the default package, other packages are - * searched. - * - * @param algorithm the name of the algorithm requested. See Appendix A in the - * Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @return a Message Digest object implementing the specified algorithm. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * caller's environment. + * Returns a new instance of <code>MessageDigest</code> representing the + * specified algorithm. + * + * @param algorithm + * the name of the digest algorithm to use. + * @return a new instance representing the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by any provider. */ public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException @@ -148,21 +98,18 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Generates a <code>MessageDigest</code> object implementing the specified - * algorithm, as supplied from the specified provider, if such an algorithm is - * available from the provider. - * - * @param algorithm the name of the algorithm requested. See Appendix A in the - * Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @param provider the name of the provider. - * @return a Message Digest object implementing the specified algorithm. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * package supplied by the requested provider. - * @throws NoSuchProviderException if the provider is not available in the - * environment. - * @throws IllegalArgumentException if the provider name is null or empty. - * @see Provider + * Returns a new instance of <code>MessageDigest</code> representing the + * specified algorithm from a named provider. + * + * @param algorithm + * the name of the digest algorithm to use. + * @param provider + * the name of the provider to use. + * @return a new instance representing the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the named provider. + * @throws NoSuchProviderException + * if the named provider was not found. */ public static MessageDigest getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException @@ -181,20 +128,18 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Generates a <code>MessageDigest</code> object implementing the specified - * algorithm, as supplied from the specified provider, if such an algorithm - * is available from the provider. Note: the provider doesn't have to be - * registered. - * - * @param algorithm the name of the algorithm requested. See Appendix A in - * the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @param provider the provider. - * @return a Message Digest object implementing the specified algorithm. - * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not - * available in the package supplied by the requested <code>provider</code>. - * @throws IllegalArgumentException if the <code>provider</code> is - * <code>null</code>. + * Returns a new instance of <code>MessageDigest</code> representing the + * specified algorithm from a designated {@link Provider}. + * + * @param algorithm + * the name of the digest algorithm to use. + * @param provider + * the {@link Provider} to use. + * @return a new instance representing the desired algorithm. + * @throws IllegalArgumentException + * if <code>provider</code> is <code>null</code>. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by {@link Provider}. * @since 1.4 * @see Provider */ @@ -233,9 +178,9 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Returns the provider of this message digest object. - * - * @return the provider of this message digest object. + * Returns the {@link Provider} of this instance. + * + * @return the {@link Provider} of this instance. */ public final Provider getProvider() { @@ -243,9 +188,9 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Updates the digest using the specified byte. - * - * @param input the byte with which to update the digest. + * Updates the digest with the byte. + * + * @param input byte to update the digest with. */ public void update(byte input) { @@ -253,12 +198,15 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Updates the digest using the specified array of bytes, starting at the - * specified offset. - * - * @param input the array of bytes. - * @param offset the offset to start from in the array of bytes. - * @param len the number of bytes to use, starting at offset. + * Updates the digest with the bytes from the array starting from the + * specified offset and using the specified length of bytes. + * + * @param input + * bytes to update the digest with. + * @param offset + * the offset to start at. + * @param len + * length of the data to update with. */ public void update(byte[] input, int offset, int len) { @@ -266,9 +214,9 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Updates the digest using the specified array of bytes. - * - * @param input the array of bytes. + * Updates the digest with the bytes of an array. + * + * @param input bytes to update the digest with. */ public void update(byte[] input) { @@ -276,10 +224,9 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Completes the hash computation by performing final operations such as - * padding. The digest is reset after this call is made. - * - * @return the array of bytes for the resulting hash value. + * Computes the final digest of the stored data. + * + * @return a byte array representing the message digest. */ public byte[] digest() { @@ -287,14 +234,15 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Completes the hash computation by performing final operations such as - * padding. The digest is reset after this call is made. - * - * @param buf An output buffer for the computed digest. - * @param offset The offset into the output buffer to begin storing the digest. - * @param len The number of bytes within buf allotted for the digest. - * @return The number of bytes placed into buf. - * @throws DigestException if an error occurs. + * Computes the final digest of the stored bytes and returns the result. + * + * @param buf + * an array of bytes to store the result in. + * @param offset + * an offset to start storing the result at. + * @param len + * the length of the buffer. + * @return Returns the length of the buffer. */ public int digest(byte[] buf, int offset, int len) throws DigestException { @@ -302,13 +250,13 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Performs a final update on the digest using the specified array of bytes, - * then completes the digest computation. That is, this method first calls - * <code>update(input)</code>, passing the input array to the <code>update() - * </code> method, then calls <code>digest()</code>. - * - * @param input the input to be updated before the digest is completed. - * @return the array of bytes for the resulting hash value. + * Computes a final update using the input array of bytes, then computes a + * final digest and returns it. It calls {@link #update(byte[])} and then + * {@link #digest(byte[])}. + * + * @param input + * an array of bytes to perform final update with. + * @return a byte array representing the message digest. */ public byte[] digest(byte[] input) { @@ -317,9 +265,9 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Returns a string representation of this message digest object. - * - * @return a string representation of the object. + * Returns a string representation of this instance. + * + * @return a string representation of this instance. */ public String toString() { @@ -327,12 +275,14 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Compares two digests for equality. Does a simple byte compare. - * - * @param digesta one of the digests to compare. - * @param digestb the other digest to compare. - * @return <code>true</code> if the digests are equal, <code>false</code> - * otherwise. + * Does a simple byte comparison of the two digests. + * + * @param digesta + * first digest to compare. + * @param digestb + * second digest to compare. + * @return <code>true</code> if both are equal, <code>false</code> + * otherwise. */ public static boolean isEqual(byte[] digesta, byte[] digestb) { @@ -346,20 +296,16 @@ public abstract class MessageDigest extends MessageDigestSpi return true; } - /** Resets the digest for further use. */ + /** Resets this instance. */ public void reset() { engineReset(); } /** - * Returns a string that identifies the algorithm, independent of - * implementation details. The name should be a standard Java Security name - * (such as <code>"SHA"</code>, <code>"MD5"</code>, and so on). See Appendix - * A in the Java Cryptography Architecture API Specification & Reference - * for information about standard algorithm names. - * - * @return the name of the algorithm. + * Returns the name of message digest algorithm. + * + * @return the name of message digest algorithm. */ public final String getAlgorithm() { @@ -367,12 +313,10 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Returns the length of the digest in bytes, or <code>0</code> if this - * operation is not supported by the provider and the implementation is not - * cloneable. - * - * @return the digest length in bytes, or <code>0</code> if this operation is - * not supported by the provider and the implementation is not cloneable. + * Returns the length of the message digest. The default is zero which means + * that the concrete implementation does not implement this method. + * + * @return length of the message digest. * @since 1.2 */ public final int getDigestLength() @@ -381,11 +325,14 @@ public abstract class MessageDigest extends MessageDigestSpi } /** - * Returns a clone if the implementation is cloneable. - * - * @return a clone if the implementation is cloneable. - * @throws CloneNotSupportedException if this is called on an implementation - * that does not support {@link Cloneable}. + * Returns a clone of this instance if cloning is supported. If it does not + * then a {@link CloneNotSupportedException} is thrown. Cloning depends on + * whether the subclass {@link MessageDigestSpi} implements {@link Cloneable} + * which contains the actual implementation of the appropriate algorithm. + * + * @return a clone of this instance. + * @throws CloneNotSupportedException + * the implementation does not support cloning. */ public Object clone() throws CloneNotSupportedException { diff --git a/libjava/classpath/java/security/NoSuchAlgorithmException.java b/libjava/classpath/java/security/NoSuchAlgorithmException.java index 412d14a16d7..518f2f72690 100644 --- a/libjava/classpath/java/security/NoSuchAlgorithmException.java +++ b/libjava/classpath/java/security/NoSuchAlgorithmException.java @@ -1,5 +1,5 @@ /* NoSuchAlgorithmException.java -- an algorithm was not available - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,4 +67,26 @@ public class NoSuchAlgorithmException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public NoSuchAlgorithmException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public NoSuchAlgorithmException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/Policy.java b/libjava/classpath/java/security/Policy.java index 03d9bbb4ed6..de1ab80ef19 100644 --- a/libjava/classpath/java/security/Policy.java +++ b/libjava/classpath/java/security/Policy.java @@ -43,49 +43,43 @@ import java.util.LinkedHashMap; import java.util.Map; /** - * <p>This is an abstract class for representing the system security policy for - * a Java application environment (specifying which permissions are available - * for code from various sources). That is, the security policy is represented - * by a <code>Policy</code> subclass providing an implementation of the abstract - * methods in this <code>Policy</code> class.</p> - * - * <p>There is only one <code>Policy</code> object in effect at any given time. - * </p> - * - * <p>The source location for the policy information utilized by the - * <code>Policy</code> object is up to the <code>Policy</code> implementation. - * The policy configuration may be stored, for example, as a flat ASCII file, as - * a serialized binary file of the <code>Policy</code> class, or as a database. - * </p> - * - * <p>The currently-installed <code>Policy</code> object can be obtained by - * calling the <code>getPolicy()</code> method, and it can be changed by a call - * to the <code>setPolicy()</code> method (by code with permission to reset the - * <code>Policy</code>).</p> - * - * <p>The <code>refresh()</code> method causes the policy object to refresh / - * reload its current configuration.</p> - * - * <p>This is implementation-dependent. For example, if the policy object stores - * its policy in configuration files, calling <code>refresh()</code> will cause - * it to re-read the configuration policy files. The refreshed policy may not - * have an effect on classes in a particular {@link ProtectionDomain}. This is - * dependent on the <code>Policy</code> provider's implementation of the - * <code>implies()</code> method and the {@link PermissionCollection} caching - * strategy.</p> - * + * <code>Policy</code> is an abstract class for managing the system security + * policy for the Java application environment. It specifies which permissions + * are available for code from various sources. The security policy is + * represented through a subclass of <code>Policy</code>. + * + * <p>Only one <code>Policy</code> is in effect at any time. A + * {@link ProtectionDomain} initializes itself with information from this class + * on the set of permssions to grant.</p> + * + * <p>The location for the actual <code>Policy</code> could be anywhere in any + * form because it depends on the Policy implementation. The default system is + * in a flat ASCII file or it could be in a database.</p> + * + * <p>The current installed <code>Policy</code> can be accessed with + * {@link #getPolicy()} and changed with {@link #setPolicy(Policy)} if the code + * has the correct permissions.</p> + * + * <p>The {@link #refresh()} method causes the <code>Policy</code> instance to + * refresh/reload its configuration. The method used to refresh depends on the + * <code>Policy</code> implementation.</p> + * + * <p>When a protection domain initializes its permissions, it uses code like + * the following:</p> + * + * <code> + * policy = Policy.getPolicy(); + * PermissionCollection perms = policy.getPermissions(myCodeSource); + * </code> + * + * <p>The protection domain passes the <code>Policy</code> handler a + * {@link CodeSource} instance which contains the codebase URL and a public key. + * The <code>Policy</code> implementation then returns the proper set of + * permissions for that {@link CodeSource}.</p> + * * <p>The default <code>Policy</code> implementation can be changed by setting - * the value of the <code>"policy.provider"</code> security property (in the - * Java security properties file) to the fully qualified name of the desired - * <code>Policy</code> implementation class. The Java security properties file - * is located in the file named <code><JAVA_HOME>/lib/security/java.security - * </code>, where <code><JAVA_HOME></code> refers to the directory where the - * SDK was installed.</p> - * - * <p><b>IMPLEMENTATION NOTE:</b> This implementation attempts to read the - * System property named <code>policy.provider</code> to find the concrete - * implementation of the <code>Policy</code>. If/when this fails, it falls back - * to a default implementation, which <b>allows everything</b>. + * the "policy.provider" security provider in the "java.security" file to the + * correct <code>Policy</code> implementation class.</p> * * @author Mark Benvenuto * @see CodeSource @@ -106,18 +100,14 @@ public abstract class Policy } /** - * Returns the installed <code>Policy</code> object. This value should not be - * cached, as it may be changed by a call to <code>setPolicy()</code>. This - * method first calls {@link SecurityManager#checkPermission(Permission)} with - * a <code>SecurityPermission("getPolicy")</code> permission to ensure it's ok - * to get the <code>Policy</code> object. - * - * @return the installed <code>Policy</code>. - * @throws SecurityException if a security manager exists and its - * <code>checkPermission()</code> method doesn't allow getting the - * <code>Policy</code> object. - * @see SecurityManager#checkPermission(Permission) - * @see #setPolicy(Policy) + * Returns the currently installed <code>Policy</code> handler. The value + * should not be cached as it can be changed any time by + * {@link #setPolicy(Policy)}. + * + * @return the current <code>Policy</code>. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public static Policy getPolicy() { @@ -129,17 +119,13 @@ public abstract class Policy } /** - * Sets the system-wide <code>Policy</code> object. This method first calls - * {@link SecurityManager#checkPermission(Permission)} with a - * <code>SecurityPermission("setPolicy")</code> permission to ensure it's ok - * to set the <code>Policy</code>. - * - * @param policy the new system <code>Policy</code> object. - * @throws SecurityException if a security manager exists and its - * <code>checkPermission()</code> method doesn't allow setting the - * <code>Policy</code>. - * @see SecurityManager#checkPermission(Permission) - * @see #getPolicy() + * Sets the <code>Policy</code> handler to a new value. + * + * @param policy + * the new <code>Policy</code> to use. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public static void setPolicy(Policy policy) { @@ -213,28 +199,27 @@ public abstract class Policy } /** - * Evaluates the global policy and returns a {@link PermissionCollection} - * object specifying the set of permissions allowed for code from the - * specified code source. - * - * @param codesource the {@link CodeSource} associated with the caller. This - * encapsulates the original location of the code (where the code came from) - * and the public key(s) of its signer. - * @return the set of permissions allowed for code from codesource according - * to the policy. The returned set of permissions must be a new mutable - * instance and it must support heterogeneous {@link Permission} types. + * Returns the set of Permissions allowed for a given {@link CodeSource}. + * + * @param codesource + * the {@link CodeSource} for which, the caller needs to find the + * set of granted permissions. + * @return a set of permissions for {@link CodeSource} specified by the + * current <code>Policy</code>. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public abstract PermissionCollection getPermissions(CodeSource codesource); /** - * Evaluates the global policy and returns a {@link PermissionCollection} - * object specifying the set of permissions allowed given the characteristics - * of the protection domain. - * - * @param domain the {@link ProtectionDomain} associated with the caller. - * @return the set of permissions allowed for the domain according to the - * policy. The returned set of permissions must be a new mutable instance and - * it must support heterogeneous {@link Permission} types. + * Returns the set of Permissions allowed for a given {@link ProtectionDomain}. + * + * @param domain + * the {@link ProtectionDomain} for which, the caller needs to find + * the set of granted permissions. + * @return a set of permissions for {@link ProtectionDomain} specified by the + * current <code>Policy.</code>. * @since 1.4 * @see ProtectionDomain * @see SecureClassLoader @@ -270,14 +255,16 @@ public abstract class Policy } /** - * Evaluates the global policy for the permissions granted to the {@link - * ProtectionDomain} and tests whether the <code>permission</code> is granted. - * - * @param domain the {@link ProtectionDomain} to test. - * @param permission the {@link Permission} object to be tested for - * implication. - * @return <code>true</code> if <code>permission</code> is a proper subset of - * a permission granted to this {@link ProtectionDomain}. + * Checks if the designated {@link Permission} is granted to a designated + * {@link ProtectionDomain}. + * + * @param domain + * the {@link ProtectionDomain} to test. + * @param permission + * the {@link Permission} to check. + * @return <code>true</code> if <code>permission</code> is implied by a + * permission granted to this {@link ProtectionDomain}. Returns + * <code>false</code> otherwise. * @since 1.4 * @see ProtectionDomain */ @@ -302,9 +289,9 @@ public abstract class Policy } /** - * Refreshes/reloads the policy configuration. The behavior of this method - * depends on the implementation. For example, calling refresh on a file-based - * policy will cause the file to be re-read. + * Causes this <code>Policy</code> instance to refresh / reload its + * configuration. The method used to refresh depends on the concrete + * implementation. */ public abstract void refresh(); } diff --git a/libjava/classpath/java/security/ProtectionDomain.java b/libjava/classpath/java/security/ProtectionDomain.java index a8a09392504..33af8fdb843 100644 --- a/libjava/classpath/java/security/ProtectionDomain.java +++ b/libjava/classpath/java/security/ProtectionDomain.java @@ -40,17 +40,14 @@ package java.security; import gnu.classpath.SystemProperties; /** - * <p>This <code>ProtectionDomain</code> class encapsulates the characteristics - * of a domain, which encloses a set of classes whose instances are granted a - * set of permissions when being executed on behalf of a given set of - * <i>Principals</i>. - * - * <p>A static set of permissions can be bound to a <code>ProtectionDomain</code> - * when it is constructed; such permissions are granted to the domain regardless - * of the {@link Policy} in force. However, to support dynamic security - * policies, a <code>ProtectionDomain</code> can also be constructed such that - * it is dynamically mapped to a set of permissions by the current {@link - * Policy} whenever a permission is checked.</p> + * This class represents a group of classes, along with their granted + * permissions. The classes are identified by a {@link CodeSource}. Thus, any + * class loaded from the specified {@link CodeSource} is treated as part of + * this domain. The set of permissions is represented by an instance of + * {@link PermissionCollection}. + * + * <p>Every class in the system will belong to one and only one + * <code>ProtectionDomain</code>.</p> * * @author Aaron M. Renn (arenn@urbanophile.com) * @version 0.0 @@ -73,15 +70,17 @@ public class ProtectionDomain private boolean staticBinding; /** - * Creates a new <code>ProtectionDomain</code> with the given {@link - * CodeSource} and {@link Permissions}. If the permissions object is not - * <code>null</code>, then <code>setReadOnly()</code> will be called on the - * passed in {@link Permissions} object. The only permissions granted to this - * domain are the ones specified; the current {@link Policy} will not be - * consulted. - * - * @param codesource the codesource associated with this domain. - * @param permissions the permissions granted to this domain + * Initializes a new instance of <code>ProtectionDomain</code> representing + * the specified {@link CodeSource} and set of permissions. No permissions + * can be added later to the {@link PermissionCollection} and this contructor + * will call the <code>setReadOnly</code> method on the specified set of + * permissions. + * + * @param codesource + * The {@link CodeSource} for this domain. + * @param permissions + * The set of permissions for this domain. + * @see PermissionCollection#setReadOnly() */ public ProtectionDomain(CodeSource codesource, PermissionCollection permissions) { @@ -89,28 +88,25 @@ public class ProtectionDomain } /** - * <p>Creates a new ProtectionDomain qualified by the given CodeSource, - * Permissions, ClassLoader and array of Principals. If the permissions - * object is not null, then <code>setReadOnly()</code> will be called on the - * passed in Permissions object. The permissions granted to this domain are - * dynamic; they include both the static permissions passed to this - * constructor, and any permissions granted to this domain by the current - * Policy at the time a permission is checked.</p> - * - * <p>This constructor is typically used by {@link ClassLoader}s and {@link - * DomainCombiner}s which delegate to <code>Policy</code> to actively - * associate the permissions granted to this domain. This constructor affords - * the Policy provider the opportunity to augment the supplied - * PermissionCollection to reflect policy changes.</p> - * - * @param codesource the CodeSource associated with this domain. - * @param permissions the permissions granted to this domain. - * @param classloader the ClassLoader associated with this domain. - * @param principals the array of Principals associated with this domain. + * This method initializes a new instance of <code>ProtectionDomain</code> + * given its {@link CodeSource}, granted permissions, associated + * {@link ClassLoader} and {@link Principal}s. + * + * <p>Similar to the previous constructor, if the designated set of + * permissions is not <code>null</code>, the <code>setReadOnly</code> method + * is called on that set.</p> + * + * @param codesource + * The {@link CodeSource} for this domain. + * @param permissions + * The permission set for this domain. + * @param classloader + * the ClassLoader associated with this domain. + * @param principals + * the array of {@link Principal}s associated with this domain. * @since 1.4 - * @see Policy#refresh() - * @see Policy#getPermissions(ProtectionDomain) - */ + * @see PermissionCollection#setReadOnly() + */ public ProtectionDomain(CodeSource codesource, PermissionCollection permissions, ClassLoader classloader, Principal[] principals) @@ -140,8 +136,8 @@ public class ProtectionDomain /** * Returns the {@link CodeSource} of this domain. - * - * @return the {@link CodeSource} of this domain which may be <code>null</code>. + * + * @return the {@link CodeSource} of this domain. * @since 1.2 */ public final CodeSource getCodeSource() @@ -151,9 +147,8 @@ public class ProtectionDomain /** * Returns the {@link ClassLoader} of this domain. - * - * @return the {@link ClassLoader} of this domain which may be - * <code>null</code>. + * + * @return the {@link ClassLoader} of this domain. * @since 1.4 */ public final ClassLoader getClassLoader() @@ -162,10 +157,9 @@ public class ProtectionDomain } /** - * Returns an array of principals for this domain. - * - * @return returns a non-null array of principals for this domain. Changes to - * this array will have no impact on the <code>ProtectionDomain</code>. + * Returns a clone of the {@link Principal}s of this domain. + * + * @return a clone of the {@link Principal}s of this domain. * @since 1.4 */ public final Principal[] getPrincipals() @@ -174,12 +168,9 @@ public class ProtectionDomain } /** - * Returns the static permissions granted to this domain. - * - * @return the static set of permissions for this domain which may be - * <code>null</code>. - * @see Policy#refresh() - * @see Policy#getPermissions(ProtectionDomain) + * Returns the {@link PermissionCollection} of this domain. + * + * @return The {@link PermissionCollection} of this domain. */ public final PermissionCollection getPermissions() { @@ -187,26 +178,13 @@ public class ProtectionDomain } /** - * <p>Check and see if this <code>ProtectionDomain</code> implies the - * permissions expressed in the <code>Permission</code> object.</p> - * - * <p>The set of permissions evaluated is a function of whether the - * <code>ProtectionDomain</code> was constructed with a static set of - * permissions or it was bound to a dynamically mapped set of permissions.</p> - * - * <p>If the <code>ProtectionDomain</code> was constructed to a statically - * bound {@link PermissionCollection} then the permission will only be checked - * against the {@link PermissionCollection} supplied at construction.</p> - * - * <p>However, if the <code>ProtectionDomain</code> was constructed with the - * constructor variant which supports dynamically binding permissions, then - * the permission will be checked against the combination of the - * {@link PermissionCollection} supplied at construction and the current - * {@link Policy} binding. - * - * @param permission the {@link Permission} object to check. - * @return <code>true</code> if <code>permission</code> is implicit to this - * <code>ProtectionDomain</code>. + * Tests whether or not the specified {@link Permission} is implied by the + * set of permissions granted to this domain. + * + * @param permission + * the {@link Permission} to test. + * @return <code>true</code> if the specified {@link Permission} is implied + * for this domain, <code>false</code> otherwise. */ public boolean implies(Permission permission) { @@ -218,9 +196,10 @@ public class ProtectionDomain } /** - * Convert a <code>ProtectionDomain</code> to a String. - * - * @return a string representation of the object. + * Returns a string representation of this object. It will include the + * {@link CodeSource} and set of permissions associated with this domain. + * + * @return A string representation of this object. */ public String toString() { diff --git a/libjava/classpath/java/security/ProviderException.java b/libjava/classpath/java/security/ProviderException.java index 2dafcec3495..4559a170812 100644 --- a/libjava/classpath/java/security/ProviderException.java +++ b/libjava/classpath/java/security/ProviderException.java @@ -1,5 +1,5 @@ /* ProviderException.java -- Generic security provider runtime exception - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,4 +67,26 @@ public class ProviderException extends RuntimeException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public ProviderException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public ProviderException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/SecureRandom.java b/libjava/classpath/java/security/SecureRandom.java index 3ee3a841d26..0d892253c03 100644 --- a/libjava/classpath/java/security/SecureRandom.java +++ b/libjava/classpath/java/security/SecureRandom.java @@ -38,6 +38,7 @@ exception statement from your version. */ package java.security; import gnu.java.security.Engine; +import gnu.java.security.jce.prng.Sha160RandomSpi; import java.util.Enumeration; import java.util.Random; @@ -126,7 +127,7 @@ public class SecureRandom extends Random } // Nothing found. Fall back to SHA1PRNG - secureRandomSpi = new gnu.java.security.provider.SHA1PRNG(); + secureRandomSpi = new Sha160RandomSpi(); } /** diff --git a/libjava/classpath/java/security/Security.java b/libjava/classpath/java/security/Security.java index d26d049c524..4e31dab75e9 100644 --- a/libjava/classpath/java/security/Security.java +++ b/libjava/classpath/java/security/Security.java @@ -60,7 +60,7 @@ import java.util.Vector; /** * This class centralizes all security properties and common security methods. - * One of its primary uses is to manage providers. + * One of its primary uses is to manage security providers. * * @author Mark Benvenuto (ivymccough@worldnet.att.net) */ @@ -110,9 +110,9 @@ public final class Security } /** - * Tries to load the vender specific security providers from the given - * base URL. Returns true if the resource could be read and completely - * parsed successfully, false otherwise. + * Tries to load the vender specific security providers from the given base + * URL. Returns true if the resource could be read and completely parsed + * successfully, false otherwise. */ private static boolean loadProviders(String baseUrl, String vendor) { @@ -133,7 +133,8 @@ public final class Security Exception exception = null; try { - providers.addElement(Class.forName(name).newInstance()); + ClassLoader sys = ClassLoader.getSystemClassLoader(); + providers.addElement(Class.forName(name, true, sys).newInstance()); } catch (ClassNotFoundException x) { @@ -166,22 +167,18 @@ public final class Security } /** - * Gets a specified property for an algorithm. The algorithm name should be a - * standard name. See Appendix A in the Java Cryptography Architecture API - * Specification & Reference for information about standard algorithm - * names. One possible use is by specialized algorithm parsers, which may map - * classes to algorithms which they understand (much like {@link Key} parsers - * do). - * - * @param algName the algorithm name. - * @param propName the name of the property to get. - * @return the value of the specified property. - * @deprecated This method used to return the value of a proprietary property - * in the master file of the "SUN" Cryptographic Service Provider in order to - * determine how to parse algorithm-specific parameters. Use the new - * provider-based and algorithm-independent {@link AlgorithmParameters} and - * {@link KeyFactory} engine classes (introduced in the Java 2 platform) - * instead. + * Returns the value associated to a designated property name for a given + * algorithm. + * + * @param algName + * the algorithm name. + * @param propName + * the name of the property to return. + * @return the value of the specified property or <code>null</code> if none + * found. + * @deprecated Use the provider-based and algorithm-independent + * {@link AlgorithmParameters} and {@link KeyFactory} engine + * classes instead. */ public static String getAlgorithmProperty(String algName, String propName) { @@ -204,37 +201,21 @@ public final class Security } /** - * <p>Adds a new provider, at a specified position. The position is the - * preference order in which providers are searched for requested algorithms. - * Note that it is not guaranteed that this preference will be respected. The - * position is 1-based, that is, <code>1</code> is most preferred, followed by - * <code>2</code>, and so on.</p> - * - * <p>If the given provider is installed at the requested position, the - * provider that used to be at that position, and all providers with a - * position greater than position, are shifted up one position (towards the - * end of the list of installed providers).</p> - * - * <p>A provider cannot be added if it is already installed.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with the string <code>"insertProvider."+provider. - * getName()</code> to see if it's ok to add a new provider. If the default - * implementation of <code>checkSecurityAccess()</code> is used (i.e., that - * method is not overriden), then this will result in a call to the security - * manager's <code>checkPermission()</code> method with a - * <code>SecurityPermission("insertProvider."+provider.getName())</code> - * permission.</p> - * - * @param provider the provider to be added. - * @param position the preference position that the caller would like for - * this provider. - * @return the actual preference position in which the provider was added, or - * <code>-1</code> if the provider was not added because it is already - * installed. - * @throws SecurityException if a security manager exists and its - * {@link SecurityManager#checkSecurityAccess(String)} method denies access - * to add a new provider. + * Inserts a new designated {@link Provider} at a designated (1-based) + * position in the current list of installed {@link Provider}s, + * + * @param provider + * the new {@link Provider} to add. + * @param position + * the position (starting from 1) of where to install + * <code>provider</code>. + * @return the actual position, in the list of installed Providers. Returns + * <code>-1</code> if <code>provider</code> was laready in the + * list. The actual position may be different than the desired + * <code>position</code>. + * @throws SecurityException + * if a {@link SecurityManager} is installed and it disallows this + * operation. * @see #getProvider(String) * @see #removeProvider(String) * @see SecurityPermission @@ -264,24 +245,17 @@ public final class Security } /** - * <p>Adds a provider to the next position available.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with the string <code>"insertProvider."+provider. - * getName()</code> to see if it's ok to add a new provider. If the default - * implementation of <code>checkSecurityAccess()</code> is used (i.e., that - * method is not overriden), then this will result in a call to the security - * manager's <code>checkPermission()</code> method with a - * <code>SecurityPermission("insertProvider."+provider.getName())</code> - * permission.</p> - * - * @param provider the provider to be added. - * @return the preference position in which the provider was added, or - * <code>-1</code> if the provider was not added because it is already - * installed. - * @throws SecurityException if a security manager exists and its - * {@link SecurityManager#checkSecurityAccess(String)} method denies access - * to add a new provider. + * Appends the designated new {@link Provider} to the current list of + * installed {@link Provider}s. + * + * @param provider + * the new {@link Provider} to append. + * @return the position (starting from 1) of <code>provider</code> in the + * current list of {@link Provider}s, or <code>-1</code> if + * <code>provider</code> was already there. + * @throws SecurityException + * if a {@link SecurityManager} is installed and it disallows this + * operation. * @see #getProvider(String) * @see #removeProvider(String) * @see SecurityPermission @@ -292,26 +266,14 @@ public final class Security } /** - * <p>Removes the provider with the specified name.</p> - * - * <p>When the specified provider is removed, all providers located at a - * position greater than where the specified provider was are shifted down - * one position (towards the head of the list of installed providers).</p> - * - * <p>This method returns silently if the provider is not installed.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with the string <code>"removeProvider."+name</code> - * to see if it's ok to remove the provider. If the default implementation of - * <code>checkSecurityAccess()</code> is used (i.e., that method is not - * overriden), then this will result in a call to the security manager's - * <code>checkPermission()</code> method with a <code>SecurityPermission( - * "removeProvider."+name)</code> permission.</p> - * - * @param name the name of the provider to remove. - * @throws SecurityException if a security manager exists and its - * {@link SecurityManager#checkSecurityAccess(String)} method denies access - * to remove the provider. + * Removes an already installed {@link Provider}, given its name, from the + * current list of installed {@link Provider}s. + * + * @param name + * the name of an already installed {@link Provider} to remove. + * @throws SecurityException + * if a {@link SecurityManager} is installed and it disallows this + * operation. * @see #getProvider(String) * @see #addProvider(Provider) */ @@ -333,9 +295,9 @@ public final class Security } /** - * Returns an array containing all the installed providers. The order of the - * providers in the array is their preference order. - * + * Returns the current list of installed {@link Provider}s as an array + * ordered according to their installation preference order. + * * @return an array of all the installed providers. */ public static Provider[] getProviders() @@ -346,11 +308,13 @@ public final class Security } /** - * Returns the provider installed with the specified name, if any. Returns - * <code>null</code> if no provider with the specified name is installed. - * - * @param name the name of the provider to get. - * @return the provider of the specified name. + * Returns an already installed {@link Provider} given its name. + * + * @param name + * the name of an already installed {@link Provider}. + * @return the {@link Provider} known by <code>name</code>. Returns + * <code>null</code> if the current list of {@link Provider}s does + * not include one named <code>name</code>. * @see #removeProvider(String) * @see #addProvider(Provider) */ @@ -376,18 +340,16 @@ public final class Security } /** - * <p>Gets a security property value.</p> - * - * <p>First, if there is a security manager, its <code>checkPermission()</code> - * method is called with a <code>SecurityPermission("getProperty."+key)</code> - * permission to see if it's ok to retrieve the specified security property - * value.</p> - * - * @param key the key of the property being retrieved. - * @return the value of the security property corresponding to key. - * @throws SecurityException if a security manager exists and its - * {@link SecurityManager#checkPermission(Permission)} method denies access - * to retrieve the specified security property value. + * Returns the value associated with a Security propery. + * + * @param key + * the key of the property to fetch. + * @return the value of the Security property associated with + * <code>key</code>. Returns <code>null</code> if no such property + * was found. + * @throws SecurityException + * if a {@link SecurityManager} is installed and it disallows this + * operation. * @see #setProperty(String, String) * @see SecurityPermission */ @@ -404,18 +366,15 @@ public final class Security } /** - * <p>Sets a security property value.</p> - * - * <p>First, if there is a security manager, its <code>checkPermission()</code> - * method is called with a <code>SecurityPermission("setProperty."+key)</code> - * permission to see if it's ok to set the specified security property value. - * </p> - * - * @param key the name of the property to be set. - * @param datum the value of the property to be set. - * @throws SecurityException if a security manager exists and its - * {@link SecurityManager#checkPermission(Permission)} method denies access - * to set the specified security property value. + * Sets or changes a designated Security property to a designated value. + * + * @param key + * the name of the property to set. + * @param datum + * the new value of the property. + * @throws SecurityException + * if a {@link SecurityManager} is installed and it disallows this + * operation. * @see #getProperty(String) * @see SecurityPermission */ @@ -432,19 +391,16 @@ public final class Security } /** - * Returns a Set of Strings containing the names of all available algorithms - * or types for the specified Java cryptographic service (e.g., Signature, - * MessageDigest, Cipher, Mac, KeyStore). Returns an empty Set if there is no - * provider that supports the specified service. For a complete list of Java - * cryptographic services, please see the Java Cryptography Architecture API - * Specification & Reference. Note: the returned set is immutable. - * - * @param serviceName the name of the Java cryptographic service (e.g., - * Signature, MessageDigest, Cipher, Mac, KeyStore). Note: this parameter is - * case-insensitive. - * @return a Set of Strings containing the names of all available algorithms - * or types for the specified Java cryptographic service or an empty set if - * no provider supports the specified service. + * For a given <i>service</i> (e.g. Signature, MessageDigest, etc...) this + * method returns the {@link Set} of all available algorithm names (instances + * of {@link String}, from all currently installed {@link Provider}s. + * + * @param serviceName + * the case-insensitive name of a service (e.g. Signature, + * MessageDigest, etc). + * @return a {@link Set} of {@link String}s containing the names of all + * algorithm names provided by all of the currently installed + * {@link Provider}s. * @since 1.4 */ public static Set getAlgorithms(String serviceName) @@ -477,53 +433,48 @@ public final class Security } /** - * <p>Returns an array containing all installed providers that satisfy the - * specified selection criterion, or <code>null</code> if no such providers - * have been installed. The returned providers are ordered according to their - * preference order.</p> - * - * <p>A cryptographic service is always associated with a particular - * algorithm or type. For example, a digital signature service is always - * associated with a particular algorithm (e.g., <i>DSA</i>), and a - * CertificateFactory service is always associated with a particular - * certificate type (e.g., <i>X.509</i>).</p> - * - * <p>The selection criterion must be specified in one of the following two - * formats:</p> - * + * Returns an array of currently installed {@link Provider}s, ordered + * according to their installation preference order, which satisfy a given + * <i>selection</i> criterion. + * + * <p>This implementation recognizes a <i>selection</i> criterion written in + * one of two following forms:</p> + * * <ul> - * <li><p><crypto_service>.<algorithm_or_type></p> - * <p>The cryptographic service name must not contain any dots.</p> - * <p>A provider satisfies the specified selection criterion iff the - * provider implements the specified algorithm or type for the specified - * cryptographic service.</p> - * <p>For example, "CertificateFactory.X.509" would be satisfied by any - * provider that supplied a CertificateFactory implementation for X.509 - * certificates.</p></li> - * - * <li><p><crypto_service>.<algorithm_or_type> <attribute_name>:<attribute_value></p> - * <p>The cryptographic service name must not contain any dots. There must - * be one or more space charaters between the the <algorithm_or_type> - * and the <attribute_name>.</p> - * <p>A provider satisfies this selection criterion iff the provider - * implements the specified algorithm or type for the specified - * cryptographic service and its implementation meets the constraint - * expressed by the specified attribute name/value pair.</p> - * <p>For example, "Signature.SHA1withDSA KeySize:1024" would be satisfied - * by any provider that implemented the SHA1withDSA signature algorithm - * with a keysize of 1024 (or larger).</p></li> + * <li><crypto_service>.<algorithm_or_type>: Where + * <i>crypto_service</i> is a case-insensitive string, similar to what has + * been described in the {@link #getAlgorithms(String)} method, and + * <i>algorithm_or_type</i> is a known case-insensitive name of an + * Algorithm, or one of its aliases. + * + * <p>For example, "CertificateFactory.X.509" would return all the installed + * {@link Provider}s which provide a <i>CertificateFactory</i> + * implementation of <i>X.509</i>.</p></li> + * + * <li><crypto_service>.<algorithm_or_type> <attribute_name>:<value>: + * Where <i>crypto_service</i> is a case-insensitive string, similar to what + * has been described in the {@link #getAlgorithms(String)} method, + * <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm + * or one of its aliases, <i>attribute_name</i> is a case-insensitive + * property name with no whitespace characters, and no dots, in-between, and + * <i>value</i> is a {@link String} with no whitespace characters in-between. + * + * <p>For example, "Signature.Sha1WithDSS KeySize:1024" would return all the + * installed {@link Provider}s which declared their ability to provide + * <i>Signature</i> services, using the <i>Sha1WithDSS</i> algorithm with + * key sizes of <i>1024</i>.</p></li> * </ul> - * - * <p>See Appendix A in the Java Cryptogaphy Architecture API Specification - * & Reference for information about standard cryptographic service names, - * standard algorithm names and standard attribute names.</p> - * - * @param filter the criterion for selecting providers. The filter is case- - * insensitive. - * @return all the installed providers that satisfy the selection criterion, - * or null if no such providers have been installed. - * @throws InvalidParameterException if the filter is not in the required - * format. + * + * @param filter + * the <i>selection</i> criterion for selecting among the installed + * {@link Provider}s. + * @return all the installed {@link Provider}s which satisfy the <i>selection</i> + * criterion. Returns <code>null</code> if no installed + * {@link Provider}s were found which satisfy the <i>selection</i> + * criterion. Returns ALL installed {@link Provider}s if + * <code>filter</code> is <code>null</code> or is an empty string. + * @throws InvalidParameterException + * if an exception occurs while parsing the <code>filter</code>. * @see #getProviders(Map) */ public static Provider[] getProviders(String filter) @@ -544,48 +495,47 @@ public final class Security return getProviders(map); } - /** - * <p>Returns an array containing all installed providers that satisfy the - * specified selection criteria, or <code>null</code> if no such providers - * have been installed. The returned providers are ordered according to their - * preference order.</p> - * - * <p>The selection criteria are represented by a map. Each map entry - * represents a selection criterion. A provider is selected iff it satisfies - * all selection criteria. The key for any entry in such a map must be in one - * of the following two formats:</p> - * - * <ul> - * <li><p><crypto_service>.<algorithm_or_type></p> - * <p>The cryptographic service name must not contain any dots.</p> - * <p>The value associated with the key must be an empty string.</p> - * <p>A provider satisfies this selection criterion iff the provider - * implements the specified algorithm or type for the specified - * cryptographic service.</p></li> - * - * <li><p><crypto_service>.<algorithm_or_type> <attribute_name></p> - * <p>The cryptographic service name must not contain any dots. There must - * be one or more space charaters between the <algorithm_or_type> and - * the <attribute_name>.</p> - * <p>The value associated with the key must be a non-empty string. A - * provider satisfies this selection criterion iff the provider implements - * the specified algorithm or type for the specified cryptographic service - * and its implementation meets the constraint expressed by the specified - * attribute name/value pair.</p></li> - * </ul> - * - * <p>See Appendix A in the Java Cryptogaphy Architecture API Specification - * & Reference for information about standard cryptographic service names, - * standard algorithm names and standard attribute names.</p> - * - * @param filter the criteria for selecting providers. The filter is case- - * insensitive. - * @return all the installed providers that satisfy the selection criteria, - * or <code>null</code> if no such providers have been installed. - * @throws InvalidParameterException if the filter is not in the required - * format. - * @see #getProviders(String) - */ + /** + * Returns an array of currently installed {@link Provider}s which satisfy a + * set of <i>selection</i> criteria. + * + * <p>The <i>selection</i> criteria are defined in a {@link Map} where each + * element specifies a <i>selection</i> querry. The <i>Keys</i> in this + * {@link Map} must be in one of the two following forms:</p> + * + * <ul> + * <li><crypto_service>.<algorithm_or_type>: Where + * <i>crypto_service</i> is a case-insensitive string, similar to what has + * been described in the {@link #getAlgorithms(String)} method, and + * <i>algorithm_or_type</i> is a case-insensitive known name of an + * Algorithm, or one of its aliases. The <i>value</i> of the entry in the + * {@link Map} for such a <i>Key</i> MUST be the empty string. + * {@link Provider}s which provide an implementation for the designated + * <i>service algorithm</i> are included in the result.</li> + * + * <li><crypto_service>.<algorithm_or_type> <attribute_name>: + * Where <i>crypto_service</i> is a case-insensitive string, similar to what + * has been described in the {@link #getAlgorithms(String)} method, + * <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm + * or one of its aliases, and <i>attribute_name</i> is a case-insensitive + * property name with no whitespace characters, and no dots, in-between. The + * <i>value</i> of the entry in this {@link Map} for such a <i>Key</i> MUST + * NOT be <code>null</code> or an empty string. {@link Provider}s which + * declare the designated <i>attribute_name</i> and <i>value</i> for the + * designated <i>service algorithm</i> are included in the result.</li> + * </ul> + * + * @param filter + * a {@link Map} of <i>selection querries</i>. + * @return all currently installed {@link Provider}s which satisfy ALL the + * <i>selection</i> criteria defined in <code>filter</code>. + * Returns ALL installed {@link Provider}s if <code>filter</code> + * is <code>null</code> or empty. + * @throws InvalidParameterException + * if an exception is encountered while parsing the syntax of the + * {@link Map}'s <i>keys</i>. + * @see #getProviders(String) + */ public static Provider[] getProviders(Map filter) { if (providers == null || providers.isEmpty()) diff --git a/libjava/classpath/java/security/Signature.java b/libjava/classpath/java/security/Signature.java index 852c959220f..845a77a8b8f 100644 --- a/libjava/classpath/java/security/Signature.java +++ b/libjava/classpath/java/security/Signature.java @@ -45,66 +45,36 @@ import java.security.cert.X509Certificate; import java.security.spec.AlgorithmParameterSpec; /** - * <p>This <code>Signature</code> class is used to provide applications the - * functionality of a digital signature algorithm. Digital signatures are used - * for authentication and integrity assurance of digital data.</p> - * - * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>, - * using <i>DSA</i> and <i>SHA-1</i>. The <i>DSA</i> algorithm using the - * <i>SHA-1</i> message digest algorithm can be specified as <code>SHA1withDSA - * </code>. In the case of <i>RSA</i>, there are multiple choices for the - * message digest algorithm, so the signing algorithm could be specified as, for - * example, <code>MD2withRSA</code>, <code>MD5withRSA</code>, or - * <code>SHA1withRSA</code>. The algorithm name must be specified, as there is - * no default.</p> - * - * <p>Like other algorithm-based classes in Java Security, <code>Signature</code> - * provides implementation-independent algorithms, whereby a caller (application - * code) requests a particular signature algorithm and is handed back a properly - * initialized <code>Signature</code> object. It is also possible, if desired, - * to request a particular algorithm from a particular provider. See the - * <code>getInstance()</code> methods.</p> - * - * <p>Thus, there are two ways to request a <code>Signature</code> algorithm - * object: by specifying either just an algorithm name, or both an algorithm - * name and a package provider.</p> - * - * <p>If just an algorithm name is specified, the system will determine if there - * is an implementation of the algorithm requested available in the environment, - * and if there is more than one, if there is a preferred one.</p> - * - * <p>If both an algorithm name and a package provider are specified, the system - * will determine if there is an implementation of the algorithm in the package - * requested, and throw an exception if there is not.</p> - * - * <p>A <code>Signature</code> object can be used to generate and verify digital - * signatures.</p> - * - * <p>There are three phases to the use of a <code>Signature</code> object for - * either signing data or verifying a signature:</p> - * + * <code>Signature</code> is used to provide an interface to digital signature + * algorithms. Digital signatures provide authentication and data integrity of + * digital data. + * + * <p>The GNU provider provides the NIST standard DSA which uses DSA and SHA-1. + * It can be specified by SHA/DSA, SHA-1/DSA or its OID. If the RSA signature + * algorithm is provided then it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The + * algorithm must be specified because there is no default.</p> + * + * <p>Signature provides implementation-independent algorithms which are + * requested by the user through the <code>getInstance()<?code> methods. It can + * be requested by specifying just the algorithm name or by specifying both the + * algorithm name and provider name.</p> + * + * <p>The three phases of using <code>Signature</code> are:</p> + * * <ol> - * <li>Initialization, with either + * <li>Initializing: * <ul> - * <li>a public key, which initializes the signature for verification - * (see <code>initVerify()</code>), or</li> - * <li>a private key (and optionally a Secure Random Number Generator), - * which initializes the signature for signing (see - * {@link #initSign(PrivateKey)} and {@link #initSign(PrivateKey, SecureRandom)} - * ).</li> - * </ul></li> - * <li>Updating<br/> - * Depending on the type of initialization, this will update the bytes to - * be signed or verified. See the update methods.<br/></li> - * <li>Signing or Verifying a signature on all updated bytes. See the - * <code>sign()</code> methods and the <code>verify()</code> method.</li> - * </ol> - * - * <p>Note that this class is abstract and extends from {@link SignatureSpi} for - * historical reasons. Application developers should only take notice of the - * methods defined in this <code>Signature</code> class; all the methods in the - * superclass are intended for cryptographic service providers who wish to - * supply their own implementations of digital signature algorithms. + * <li>It must be initialized with a private key for signing.</li> + * <li>It must be initialized with a public key for verifying.</li> + * </li> + * + * <li>Updating: + * <p>Update the bytes for signing or verifying with calls to update.</p> + * </li> + * + * <li>Signing or Verify the signature on the currently stored bytes by + * calling sign or verify.</li> + * </ol> * * @author Mark Benvenuto (ivymccough@worldnet.att.net) */ @@ -114,38 +84,38 @@ public abstract class Signature extends SignatureSpi private static final String SIGNATURE = "Signature"; /** - * Possible <code>state</code> value, signifying that this signature object - * has not yet been initialized. + * Possible state value which signifies that this instance has not yet been + * initialized. */ protected static final int UNINITIALIZED = 0; - // Constructor. - // ------------------------------------------------------------------------ - /** - * Possible <code>state</code> value, signifying that this signature object - * has been initialized for signing. + * Possible state value which signifies that this instance has been + * initialized for signing purposes. */ protected static final int SIGN = 2; /** - * Possible <code>state</code> value, signifying that this signature object - * has been initialized for verification. + * Possible state value which signifies that this instance has been + * initialized for verification purposes. */ protected static final int VERIFY = 3; - /** Current state of this signature object. */ + /** Current sate of this instance. */ protected int state = UNINITIALIZED; private String algorithm; Provider provider; + // Constructor. + // ------------------------------------------------------------------------ + /** - * Creates a <code>Signature</code> object for the specified algorithm. - * - * @param algorithm the standard string name of the algorithm. See Appendix A - * in the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. + * Constructs a new <code>Signature</code> instance for a designated digital + * signature algorithm. + * + * @param algorithm + * the algorithm to use. */ protected Signature(String algorithm) { @@ -154,19 +124,14 @@ public abstract class Signature extends SignatureSpi } /** - * Generates a <code>Signature</code> object that implements the specified - * digest algorithm. If the default provider package provides an - * implementation of the requested digest algorithm, an instance of - * <code>Signature</code> containing that implementation is returned. If the - * algorithm is not available in the default package, other packages are - * searched. - * - * @param algorithm the standard name of the algorithm requested. See Appendix - * A in the Java Cryptography Architecture API Specification & Reference - * for information about standard algorithm names. - * @return the new Signature object. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * environment. + * Returns an instance of <code>Signature</code> representing the specified + * signature. + * + * @param algorithm + * the algorithm to use. + * @return a new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by any provider. */ public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException @@ -188,22 +153,20 @@ public abstract class Signature extends SignatureSpi } /** - * Generates a <code>Signature</code> object implementing the specified - * algorithm, as supplied from the specified provider, if such an algorithm - * is available from the provider. - * - * @param algorithm the name of the algorithm requested. See Appendix A in - * the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @param provider the name of the provider. - * @return the new <code>Signature</code> object. - * @throws NoSuchAlgorithmException if the algorithm is not available in the - * package supplied by the requested provider. - * @throws NoSuchProviderException if the provider is not available in the - * environment. - * @throws IllegalArgumentException if the provider name is <code>null</code> - * or empty. - * @see Provider + * Returns an instance of <code>Signature</code> representing the specified + * signature from the named provider. + * + * @param algorithm + * the algorithm to use. + * @param provider + * the name of the provider to use. + * @return a new instance repesenting the desired algorithm. + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code> or is an empty string. + * @throws NoSuchProviderException + * if the named provider was not found. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the named provider. */ public static Signature getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException @@ -219,22 +182,16 @@ public abstract class Signature extends SignatureSpi } /** - * Generates a <code>Signature</code> object implementing the specified - * algorithm, as supplied from the specified provider, if such an algorithm - * is available from the provider. Note: the provider doesn't have to be - * registered. - * - * @param algorithm the name of the algorithm requested. See Appendix A in - * the Java Cryptography Architecture API Specification & Reference for - * information about standard algorithm names. - * @param provider the provider. - * @return the new <code>Signature</code> object. - * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not - * available in the package supplied by the requested <code>provider</code>. - * @throws IllegalArgumentException if the <code>provider</code> is - * <code>null</code>. - * @since 1.4 - * @see Provider + * Returns an instance of <code>Signature</code> representing the specified + * signature from the specified {@link Provider}. + * + * @param algorithm + * the algorithm to use. + * @param provider + * the {@link Provider} to use. + * @return a new instance repesenting the desired algorithm. + * @throws NoSuchAlgorithmException + * if the algorithm is not implemented by the {@link Provider}. */ public static Signature getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException @@ -271,9 +228,9 @@ public abstract class Signature extends SignatureSpi } /** - * Returns the provider of this signature object. - * - * @return the provider of this signature object. + * Returns the {@link Provider} of this instance. + * + * @return the {@link Provider} of this instance. */ public final Provider getProvider() { @@ -281,12 +238,12 @@ public abstract class Signature extends SignatureSpi } /** - * Initializes this object for verification. If this method is called again - * with a different argument, it negates the effect of this call. - * - * @param publicKey the public key of the identity whose signature is going - * to be verified. - * @throws InvalidKeyException if the key is invalid. + * Initializes this instance with the public key for verification purposes. + * + * @param publicKey + * the public key to verify with. + * @throws InvalidKeyException + * if the key is invalid. */ public final void initVerify(PublicKey publicKey) throws InvalidKeyException { @@ -295,20 +252,16 @@ public abstract class Signature extends SignatureSpi } /** - * <p>Initializes this object for verification, using the public key from the - * given certificate.</p> - * - * <p>If the certificate is of type <i>X.509</i> and has a <i>key usage</i> - * extension field marked as <i>critical</i>, and the value of the <i>key - * usage</i> extension field implies that the public key in the certificate - * and its corresponding private key are not supposed to be used for digital - * signatures, an {@link InvalidKeyException} is thrown.</p> - * - * @param certificate the certificate of the identity whose signature is - * going to be verified. - * @throws InvalidKeyException if the public key in the certificate is not - * encoded properly or does not include required parameter information or - * cannot be used for digital signature purposes. + * Verify a signature with a designated {@link Certificate}. This is a FIPS + * 140-1 compatible method since it verifies a signature with a certificate. + * + * <p>If the {@link Certificate} is an X.509 one, has a <i>KeyUsage</i> + * parameter and that parameter indicates this key is not to be used for + * signing then an exception is thrown.</p> + * + * @param certificate + * a {@link Certificate} containing a public key to verify with. + * @throws InvalidKeyException if the key is invalid. */ public final void initVerify(Certificate certificate) throws InvalidKeyException @@ -326,12 +279,12 @@ public abstract class Signature extends SignatureSpi } /** - * Initialize this object for signing. If this method is called again with a - * different argument, it negates the effect of this call. - * - * @param privateKey the private key of the identity whose signature is going - * to be generated. - * @throws InvalidKeyException if the key is invalid. + * Initializes this class with the private key for signing purposes. + * + * @param privateKey + * the private key to sign with. + * @throws InvalidKeyException + * if the key is invalid. */ public final void initSign(PrivateKey privateKey) throws InvalidKeyException { @@ -340,13 +293,15 @@ public abstract class Signature extends SignatureSpi } /** - * Initialize this object for signing. If this method is called again with a - * different argument, it negates the effect of this call. - * - * @param privateKey the private key of the identity whose signature is going - * to be generated. - * @param random the source of randomness for this signature. - * @throws InvalidKeyException if the key is invalid. + * Initializes this class with the private key and source of randomness for + * signing purposes. + * + * @param privateKey + * the private key to sign with. + * @param random + * the {@link SecureRandom} to use. + * @throws InvalidKeyException + * if the key is invalid. */ public final void initSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException @@ -356,18 +311,12 @@ public abstract class Signature extends SignatureSpi } /** - * <p>Returns the signature bytes of all the data updated. The format of the - * signature depends on the underlying signature scheme.</p> - * - * <p>A call to this method resets this signature object to the state it was - * in when previously initialized for signing via a call to - * <code>initSign(PrivateKey)</code>. That is, the object is reset and - * available to generate another signature from the same signer, if desired, - * via new calls to <code>update()</code> and <code>sign()</code>.</p> - * - * @return the signature bytes of the signing operation's result. - * @throws SignatureException if this signature object is not initialized - * properly. + * Returns the signature bytes of all the data fed to this instance. The + * format of the output depends on the underlying signature algorithm. + * + * @return the signature bytes. + * @throws SignatureException + * if the engine is not properly initialized. */ public final byte[] sign() throws SignatureException { @@ -378,21 +327,27 @@ public abstract class Signature extends SignatureSpi } /** - * <p>Finishes the signature operation and stores the resulting signature - * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset - * </code>. The format of the signature depends on the underlying signature - * scheme.</p> - * - * <p>This signature object is reset to its initial state (the state it was - * in after a call to one of the <code>initSign()</code> methods) and can be - * reused to generate further signatures with the same private key.</p> - * - * @param outbuf buffer for the signature result. - * @param offset offset into outbuf where the signature is stored. - * @param len number of bytes within outbuf allotted for the signature. - * @return the number of bytes placed into outbuf. - * @throws SignatureException if an error occurs or len is less than the - * actual signature length. + * Generates signature bytes of all the data fed to this instance and stores + * it in the designated array. The format of the result depends on the + * underlying signature algorithm. + * + * <p>After calling this method, the instance is reset to its initial state + * and can then be used to generate additional signatures.</p> + * + * <p><b>IMPLEMENTATION NOTE:</b> Neither this method nor the GNU provider + * will return partial digests. If <code>len</code> is less than the + * signature length, this method will throw a {@link SignatureException}. If + * it is greater than or equal then it is ignored.</p> + * + * @param outbuf + * array of bytes of where to store the resulting signature bytes. + * @param offset + * the offset to start at in the array. + * @param len + * the number of the bytes to use in the array. + * @return the real number of bytes used. + * @throws SignatureException + * if the engine is not properly initialized. * @since 1.2 */ public final int sign(byte[] outbuf, int offset, int len) @@ -405,20 +360,14 @@ public abstract class Signature extends SignatureSpi } /** - * <p>Verifies the passed-in signature.</p> - * - * <p>A call to this method resets this signature object to the state it was - * in when previously initialized for verification via a call to - * <code>initVerify(PublicKey)</code>. That is, the object is reset and - * available to verify another signature from the identity whose public key - * was specified in the call to <code>initVerify()</code>.</p> - * - * @param signature the signature bytes to be verified. - * @return <code>true</code> if the signature was verified, <code>false</code> - * if not. - * @throws SignatureException if this signature object is not initialized - * properly, or the passed-in signature is improperly encoded or of the wrong - * type, etc. + * Verifies a designated signature. + * + * @param signature + * the signature bytes to verify. + * @return <code>true</code> if verified, <code>false</code> otherwise. + * @throws SignatureException + * if the engine is not properly initialized or the signature does + * not check. */ public final boolean verify(byte[]signature) throws SignatureException { @@ -429,28 +378,24 @@ public abstract class Signature extends SignatureSpi } /** - * <p>Verifies the passed-in <code>signature</code> in the specified array of - * bytes, starting at the specified <code>offset</code>.</p> - * - * <p>A call to this method resets this signature object to the state it was - * in when previously initialized for verification via a call to - * <code>initVerify(PublicKey)</code>. That is, the object is reset and - * available to verify another signature from the identity whose public key - * was specified in the call to <code>initVerify()</code>.</p> - * - * @param signature the signature bytes to be verified. - * @param offset the offset to start from in the array of bytes. - * @param length the number of bytes to use, starting at offset. - * @return <code>true</code> if the signature was verified, <code>false</code> - * if not. - * @throws SignatureException if this signature object is not initialized - * properly, or the passed-in <code>signature</code> is improperly encoded or - * of the wrong type, etc. - * @throws IllegalArgumentException if the <code>signature</code> byte array - * is <code>null</code>, or the <code>offset</code> or <code>length</code> is - * less than <code>0</code>, or the sum of the <code>offset</code> and - * <code>length</code> is greater than the length of the <code>signature</code> - * byte array. + * Verifies a designated signature. + * + * @param signature + * the signature bytes to verify. + * @param offset + * the offset to start at in the array. + * @param length + * the number of the bytes to use from the array. + * @return <code>true</code> if verified, <code>false</code> otherwise. + * @throws IllegalArgumentException + * if the <code>signature</code> byte array is <code>null</code>, + * or the <code>offset</code> or <code>length</code> is less + * than <code>0</code>, or the sum of the <code>offset</code> + * and <code>length</code> is greater than the length of the + * <code>signature</code> byte array. + * @throws SignatureException + * if the engine is not properly initialized or the signature does + * not check. */ public final boolean verify(byte[] signature, int offset, int length) throws SignatureException @@ -471,11 +416,12 @@ public abstract class Signature extends SignatureSpi } /** - * Updates the data to be signed or verified by a byte. - * - * @param b the byte to use for the update. - * @throws SignatureException if this signature object is not initialized - * properly. + * Updates the data to be signed or verified with the specified byte. + * + * @param b + * the byte to update with. + * @throws SignatureException + * if the engine is not properly initialized. */ public final void update(byte b) throws SignatureException { @@ -486,12 +432,12 @@ public abstract class Signature extends SignatureSpi } /** - * Updates the data to be signed or verified, using the specified array of - * bytes. - * - * @param data the byte array to use for the update. - * @throws SignatureException if this signature object is not initialized - * properly. + * Updates the data to be signed or verified with the specified bytes. + * + * @param data + * the array of bytes to use. + * @throws SignatureException + * if the engine is not properly initialized. */ public final void update(byte[]data) throws SignatureException { @@ -502,14 +448,16 @@ public abstract class Signature extends SignatureSpi } /** - * Updates the data to be signed or verified, using the specified array of - * bytes, starting at the specified offset. - * - * @param data the array of bytes. - * @param off the offset to start from in the array of bytes. - * @param len the number of bytes to use, starting at offset. - * @throws SignatureException if this signature object is not initialized - * properly. + * Updates the data to be signed or verified with the specified bytes. + * + * @param data + * an array of bytes to use. + * @param off + * the offset to start at in the array. + * @param len + * the number of bytes to use from the array. + * @throws SignatureException + * if the engine is not properly initialized. */ public final void update(byte[]data, int off, int len) throws SignatureException @@ -521,9 +469,10 @@ public abstract class Signature extends SignatureSpi } /** - * Returns the name of the algorithm for this signature object. - * - * @return the name of the algorithm for this signature object. + * Returns the name of the algorithm currently used. The names of algorithms + * are usually SHA/DSA or SHA/RSA. + * + * @return name of algorithm. */ public final String getAlgorithm() { @@ -531,11 +480,9 @@ public abstract class Signature extends SignatureSpi } /** - * Returns a string representation of this signature object, providing - * information that includes the state of the object and the name of the - * algorithm used. - * - * @return a string representation of this signature object. + * Returns a rstring representation of this instance. + * + * @return a rstring representation of this instance. */ public String toString() { @@ -543,22 +490,16 @@ public abstract class Signature extends SignatureSpi } /** - * Sets the specified algorithm parameter to the specified value. This method - * supplies a general-purpose mechanism through which it is possible to set - * the various parameters of this object. A parameter may be any settable - * parameter for the algorithm, such as a parameter size, or a source of - * random bits for signature generation (if appropriate), or an indication of - * whether or not to perform a specific but optional computation. A uniform - * algorithm-specific naming scheme for each parameter is desirable but left - * unspecified at this time. - * - * @param param the string identifier of the parameter. - * @param value the parameter value. - * @throws InvalidParameterException if param is an invalid parameter for this - * signature algorithm engine, the parameter is already set and cannot be set - * again, a security exception occurs, and so on. - * @see #getParameter(String) - * @deprecated Use setParameter(AlgorithmParameterSpec). + * Sets the specified algorithm parameter to the specified value. + * + * @param param + * the parameter name. + * @param value + * the parameter value. + * @throws InvalidParameterException + * if the parameter is invalid, the parameter is already set and + * can not be changed, a security exception occured, etc. + * @deprecated use the other setParameter */ public final void setParameter(String param, Object value) throws InvalidParameterException @@ -567,12 +508,16 @@ public abstract class Signature extends SignatureSpi } /** - * Initializes this signature engine with the specified parameter set. - * - * @param params the parameters. - * @throws InvalidAlgorithmParameterException if the given parameters are - * inappropriate for this signature engine. - * @see #getParameters() + * Sets the signature engine with the specified {@link AlgorithmParameterSpec}. + * + * <p>By default, and unless overriden by the concrete SPI, this method always + * throws an {@link UnsupportedOperationException}.</p> + * + * @param params + * the parameters to use for intializing this instance. + * @throws InvalidParameterException + * if the parameter is invalid, the parameter is already set and + * cannot be changed, a security exception occured, etc. */ public final void setParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException @@ -581,17 +526,11 @@ public abstract class Signature extends SignatureSpi } /** - * <p>Returns the parameters used with this signature object.</p> - * - * <p>The returned parameters may be the same that were used to initialize - * this signature, or may contain a combination of default and randomly - * generated parameter values used by the underlying signature implementation - * if this signature requires algorithm parameters but was not initialized - * with any. - * - * @return the parameters used with this signature, or <code>null</code> if - * this signature does not use any parameters. - * @see #setParameter(AlgorithmParameterSpec) + * Return the parameters of the algorithm used in this instance as an + * {@link AlgorithmParameters}. + * + * @return the parameters used with this instance, or <code>null</code> if + * this instance does not use any parameters. */ public final AlgorithmParameters getParameters() { @@ -599,22 +538,14 @@ public abstract class Signature extends SignatureSpi } /** - * Gets the value of the specified algorithm parameter. This method supplies - * a general-purpose mechanism through which it is possible to get the various - * parameters of this object. A parameter may be any settable parameter for - * the algorithm, such as a parameter size, or a source of random bits for - * signature generation (if appropriate), or an indication of whether or not - * to perform a specific but optional computation. A uniform - * algorithm-specific naming scheme for each parameter is desirable but left - * unspecified at this time. - * - * @param param the string name of the parameter. - * @return the object that represents the parameter value, or null if there - * is none. - * @throws InvalidParameterException if param is an invalid parameter for this - * engine, or another exception occurs while trying to get this parameter. - * @see #setParameter(String, Object) - * @deprecated + * Returns the value for the specified algorithm parameter. + * + * @param param + * the parameter name. + * @return the parameter value. + * @throws InvalidParameterException + * if the parameter is invalid. + * @deprecated use the other getParameter */ public final Object getParameter(String param) throws InvalidParameterException @@ -623,11 +554,11 @@ public abstract class Signature extends SignatureSpi } /** - * Returns a clone if the implementation is cloneable. - * - * @return a clone if the implementation is cloneable. - * @throws CloneNotSupportedException if this is called on an implementation - * that does not support {@link Cloneable}. + * Returns a clone of this instance. + * + * @return a clone of this instace. + * @throws CloneNotSupportedException + * if the implementation does not support cloning. */ public Object clone() throws CloneNotSupportedException { diff --git a/libjava/classpath/java/security/SignatureException.java b/libjava/classpath/java/security/SignatureException.java index e294c16c3f6..b097bacfcf1 100644 --- a/libjava/classpath/java/security/SignatureException.java +++ b/libjava/classpath/java/security/SignatureException.java @@ -1,5 +1,5 @@ /* SignatureException.java -- Generic error in signature - Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,4 +67,26 @@ public class SignatureException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public SignatureException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public SignatureException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/SignatureSpi.java b/libjava/classpath/java/security/SignatureSpi.java index 471a73d17cd..25d49dedd43 100644 --- a/libjava/classpath/java/security/SignatureSpi.java +++ b/libjava/classpath/java/security/SignatureSpi.java @@ -40,14 +40,10 @@ package java.security; import java.security.spec.AlgorithmParameterSpec; /** - * <p>This class defines the <i>Service Provider Interface (SPI)</i> for the - * {@link Signature} class, which is used to provide the functionality of a + * <code>SignatureSpi</code> defines the Service Provider Interface (SPI) for + * the {@link Signature} class. The signature class provides an interface to a * digital signature algorithm. Digital signatures are used for authentication - * and integrity assurance of digital data.</p> - * - * <p>All the abstract methods in this class must be implemented by each - * cryptographic service provider who wishes to supply the implementation of a - * particular signature algorithm. + * and integrity of data. * * @author Mark Benvenuto (ivymccough@worldnet.att.net) * @since 1.2 @@ -55,50 +51,51 @@ import java.security.spec.AlgorithmParameterSpec; */ public abstract class SignatureSpi { - /** Application-specified source of randomness. */ + /** Source of randomness. */ protected SecureRandom appRandom; + /** + * Creates a new instance of <code>SignatureSpi</code>. + */ public SignatureSpi() { appRandom = null; } /** - * Initializes this signature object with the specified public key for - * verification operations. - * - * @param publicKey the public key of the identity whose signature is going - * to be verified. - * @throws InvalidKeyException if the key is improperly encoded, parameters - * are missing, and so on. + * Initializes this instance with the public key for verification purposes. + * + * @param publicKey + * the public key to verify with. + * @throws InvalidKeyException + * if the key is invalid. */ protected abstract void engineInitVerify(PublicKey publicKey) throws InvalidKeyException; /** - * Initializes this signature object with the specified private key for - * signing operations. - * - * @param privateKey the private key of the identity whose signature will be - * generated. - * @throws InvalidKeyException if the key is improperly encoded, parameters - * are missing, and so on. + * Initializes this instance with the private key for signing purposes. + * + * @param privateKey + * the private key to sign with. + * @throws InvalidKeyException + * if the key is invalid. */ protected abstract void engineInitSign(PrivateKey privateKey) throws InvalidKeyException; /** - * <p>Initializes this signature object with the specified private key and - * source of randomness for signing operations.</p> - * - * <p>This concrete method has been added to this previously-defined abstract - * class. (For backwards compatibility, it cannot be abstract.)</p> - * - * @param privateKey the private key of the identity whose signature will be - * generated. - * @param random the source of randomness. - * @throws InvalidKeyException if the key is improperly encoded, parameters - * are missing, and so on. + * Initializes this instance with the private key and source of randomness for + * signing purposes. + * + * <p>This method cannot be abstract for backward compatibility reasons.</p> + * + * @param privateKey + * the private key to sign with. + * @param random + * the {@link SecureRandom} to use. + * @throws InvalidKeyException + * if the key is invalid. * @since 1.2 */ protected void engineInitSign(PrivateKey privateKey, SecureRandom random) @@ -109,57 +106,63 @@ public abstract class SignatureSpi } /** - * Updates the data to be signed or verified using the specified byte. - * - * @param b the byte to use for the update. - * @throws SignatureException if the engine is not initialized properly. + * Updates the data to be signed or verified with the specified byte. + * + * @param b + * byte to update with. + * @throws SignatureException + * if the engine is not properly initialized. */ protected abstract void engineUpdate(byte b) throws SignatureException; /** - * Updates the data to be signed or verified, using the specified array of - * bytes, starting at the specified offset. - * - * @param b the array of bytes. - * @param off the offset to start from in the array of bytes. - * @param len the number of bytes to use, starting at offset. - * @throws SignatureException if the engine is not initialized properly. + * Updates the data to be signed or verified with the specified bytes. + * + * @param b + * the array of bytes to use. + * @param off + * the offset to start at in the array. + * @param len + * the number of the bytes to use from the array. + * @throws SignatureException + * if the engine is not properly initialized. */ protected abstract void engineUpdate(byte[] b, int off, int len) throws SignatureException; /** - * Returns the signature bytes of all the data updated so far. The format of - * the signature depends on the underlying signature scheme. - * - * @return the signature bytes of the signing operation's result. - * @throws SignatureException if the engine is not initialized properly. + * Returns the signature bytes of all the data fed to this instance. The + * format of the output depends on the underlying signature algorithm. + * + * @return the signature bytes. + * @throws SignatureException + * if the engine is not properly initialized. */ protected abstract byte[] engineSign() throws SignatureException; /** - * <p>Finishes this signature operation and stores the resulting signature - * bytes in the provided buffer <code>outbuf</code>, starting at <code>offset - * </code>. The format of the signature depends on the underlying signature - * scheme.</p> - * - * <p>The signature implementation is reset to its initial state (the state it - * was in after a call to one of the <code>engineInitSign()</code> methods) - * and can be reused to generate further signatures with the same private key. - * This method should be abstract, but we leave it concrete for binary - * compatibility. Knowledgeable providers should override this method.</p> - * - * @param outbuf buffer for the signature result. - * @param offset offset into outbuf where the signature is stored. - * @param len number of bytes within outbuf allotted for the signature. Both - * this default implementation and the <b>GNU</b> provider do not return - * partial digests. If the value of this parameter is less than the actual - * signature length, this method will throw a {@link SignatureException}. This - * parameter is ignored if its value is greater than or equal to the actual - * signature length. - * @return the number of bytes placed into <code>outbuf</code>. - * @throws SignatureException if an error occurs or len is less than the - * actual signature length. + * Generates signature bytes of all the data fed to this instance and stores + * the result in the designated array. The format of the output depends on + * the underlying signature algorithm. + * + * <p>This method cannot be abstract for backward compatibility reasons. + * After calling this method, the signature is reset to its initial state and + * can be used to generate additional signatures.</p> + * + * <p><b>IMPLEMENTATION NOTE:</b>: Neither this method nor the GNU provider + * will return partial digests. If <code>len</code> is less than the + * signature length, this method will throw a {@link SignatureException}. If + * it is greater than or equal then it is ignored.</p> + * + * @param outbuf + * the array of bytes to store the result in. + * @param offset + * the offset to start at in the array. + * @param len + * the number of the bytes to use in the array. + * @return the real number of bytes used. + * @throws SignatureException + * if the engine is not properly initialized. * @since 1.2 */ protected int engineSign(byte[] outbuf, int offset, int len) @@ -174,31 +177,32 @@ public abstract class SignatureSpi } /** - * Verifies the passed-in signature. - * - * @param sigBytes the signature bytes to be verified. - * @return <code>true</code> if the signature was verified, <code>false</code> - * if not. - * @throws SignatureException if the engine is not initialized properly, or - * the passed-in signature is improperly encoded or of the wrong type, etc. + * Verifies a designated signature. + * + * @param sigBytes + * the signature bytes to verify. + * @return <code>true</code> if verified, <code>false</code> otherwise. + * @throws SignatureException + * if the engine is not properly initialized or if it is the wrong + * signature. */ protected abstract boolean engineVerify(byte[] sigBytes) throws SignatureException; /** - * <p>Verifies the passed-in <code>signature</code> in the specified array of - * bytes, starting at the specified <code>offset</code>.</p> - * - * <p>Note: Subclasses should overwrite the default implementation.</p> - * - * @param sigBytes the signature bytes to be verified. - * @param offset the offset to start from in the array of bytes. - * @param length the number of bytes to use, starting at offset. - * @return <code>true</code> if the signature was verified, <code>false</code> - * if not. - * @throws SignatureException if the engine is not initialized properly, or - * the passed-in <code>signature</code> is improperly encoded or of the wrong - * type, etc. + * Convenience method which calls the method with the same name and one + * argument after copying the designated bytes into a temporary byte array. + * Subclasses may override this method for performance reasons. + * + * @param sigBytes + * the array of bytes to use. + * @param offset + * the offset to start from in the array of bytes. + * @param length + * the number of bytes to use, starting at offset. + * @return <code>true</code> if verified, <code>false</code> otherwise. + * @throws SignatureException + * if the engine is not properly initialized. */ protected boolean engineVerify(byte[] sigBytes, int offset, int length) throws SignatureException @@ -209,35 +213,32 @@ public abstract class SignatureSpi } /** - * Sets the specified algorithm parameter to the specified value. This method - * supplies a general-purpose mechanism through which it is possible to set - * the various parameters of this object. A parameter may be any settable - * parameter for the algorithm, such as a parameter size, or a source of - * random bits for signature generation (if appropriate), or an indication of - * whether or not to perform a specific but optional computation. A uniform - * algorithm-specific naming scheme for each parameter is desirable but left - * unspecified at this time. - * - * @param param the string identifier of the parameter. - * @param value the parameter value. - * @throws InvalidParameterException if <code>param</code> is an invalid - * parameter for this signature algorithm engine, the parameter is already set - * and cannot be set again, a security exception occurs, and so on. - * @deprecated Replaced by engineSetParameter(AlgorithmParameterSpec). + * Sets the specified algorithm parameter to the specified value. + * + * @param param + * the parameter name. + * @param value + * the parameter value. + * @throws InvalidParameterException + * if the parameter invalid, the parameter is already set and + * cannot be changed, a security exception occured, etc. + * @deprecated use the other setParameter. */ protected abstract void engineSetParameter(String param, Object value) throws InvalidParameterException; /** - * This method is overridden by providers to initialize this signature engine - * with the specified parameter set. - * - * @param params the parameters. - * @throws UnsupportedOperationException if this method is not overridden by - * a provider. - * @throws InvalidAlgorithmParameterException if this method is overridden by - * a provider and the the given parameters are inappropriate for this - * signature engine. + * Sets the signature engine with the specified {@link AlgorithmParameterSpec}. + * + * <p>This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.</p> + * + * @param params + * the parameters. + * @throws InvalidParameterException + * if the parameter is invalid, the parameter is already set and + * cannot be changed, a security exception occured, etc. */ protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException @@ -246,20 +247,16 @@ public abstract class SignatureSpi } /** - * <p>This method is overridden by providers to return the parameters used - * with this signature engine, or <code>null</code> if this signature engine - * does not use any parameters.</p> - * - * <p>The returned parameters may be the same that were used to initialize - * this signature engine, or may contain a combination of default and randomly - * generated parameter values used by the underlying signature implementation - * if this signature engine requires algorithm parameters but was not - * initialized with any.</p> - * - * @return the parameters used with this signature engine, or <code>null</code> - * if this signature engine does not use any parameters. - * @throws UnsupportedOperationException if this method is not overridden by - * a provider. + * The default implementaion of this method always throws a + * {@link UnsupportedOperationException}. It MUST be overridden by concrete + * implementations to return the appropriate {@link AlgorithmParameters} for + * this signature engine (or <code>null</code> when that engine does not use + * any parameters. + * + * @return the parameters used with this signature engine, or + * <code>null</code> if it does not use any parameters. + * @throws UnsupportedOperationException + * always. */ protected AlgorithmParameters engineGetParameters() { @@ -267,33 +264,24 @@ public abstract class SignatureSpi } /** - * Gets the value of the specified algorithm parameter. This method supplies - * a general-purpose mechanism through which it is possible to get the various - * parameters of this object. A parameter may be any settable parameter for - * the algorithm, such as a parameter size, or a source of random bits for - * signature generation (if appropriate), or an indication of whether or not - * to perform a specific but optional computation. A uniform algorithm-specific - * naming scheme for each parameter is desirable but left unspecified at this - * time. - * - * @param param the string name of the parameter. - * @return the object that represents the parameter value, or <code>null</code> - * if there is none. - * @throws InvalidParameterException if <code>param</code> is an invalid - * parameter for this engine, or another exception occurs while trying to get - * this parameter. - * @deprecated + * Returns the value for the specified algorithm parameter. + * + * @param param + * the parameter name. + * @return the parameter value. + * @throws InvalidParameterException + * if the parameter is invalid. + * @deprecated use the other getParameter */ protected abstract Object engineGetParameter(String param) throws InvalidParameterException; /** - * Returns a clone if the implementation is cloneable. - * - * @return a clone if the implementation is cloneable. - * @throws CloneNotSupportedException if this is called on an implementation - * that does not support {@link Cloneable}. - * @see Cloneable + * Returns a clone of this instance. + * + * @return a clone of this instance. + * @throws CloneNotSupportedException + * if the implementation does not support cloning. */ public Object clone() throws CloneNotSupportedException { diff --git a/libjava/classpath/java/security/SignedObject.java b/libjava/classpath/java/security/SignedObject.java index d565b2ea3b4..be5a6746122 100644 --- a/libjava/classpath/java/security/SignedObject.java +++ b/libjava/classpath/java/security/SignedObject.java @@ -46,82 +46,34 @@ import java.io.ObjectOutputStream; import java.io.Serializable; /** - * <p><code>SignedObject</code> is a class for the purpose of creating authentic - * runtime objects whose integrity cannot be compromised without being detected. - * </p> - * - * <p>More specifically, a <code>SignedObject</code> contains another - * {@link Serializable} object, the (to-be-)signed object and its signature.</p> - * - * <p>The signed object is a <i>"deep copy"</i> (in serialized form) of an - * original object. Once the copy is made, further manipulation of the original - * object has no side effect on the copy.</p> - * - * <p>The underlying signing algorithm is designated by the {@link Signature} - * object passed to the constructor and the <code>verify()</code> method. A - * typical usage for signing is the following:</p> - * - * <pre> - * Signature signingEngine = Signature.getInstance(algorithm, provider); - * SignedObject so = new SignedObject(myobject, signingKey, signingEngine); - * </pre> - * - * <p>A typical usage for verification is the following (having received - * <code>SignedObject</code> so):</p> - * - * <pre> - * Signature verificationEngine = Signature.getInstance(algorithm, provider); - * if (so.verify(publickey, verificationEngine)) - * try - * { - * Object myobj = so.getObject(); - * } - * catch (ClassNotFoundException ignored) {}; - * </pre> - * - * <p>Several points are worth noting. First, there is no need to initialize the - * signing or verification engine, as it will be re-initialized inside the - * constructor and the <code>verify()</code> method. Secondly, for verification - * to succeed, the specified public key must be the public key corresponding to - * the private key used to generate the <code>SignedObject</code>.</p> - * - * <p>More importantly, for flexibility reasons, the <code>constructor</code> - * and <code>verify()</code> method allow for customized signature engines, - * which can implement signature algorithms that are not installed formally as - * part of a crypto provider. However, it is crucial that the programmer writing - * the verifier code be aware what {@link Signature} engine is being used, as - * its own implementation of the <code>verify()</code> method is invoked to - * verify a signature. In other words, a malicious {@link Signature} may choose - * to always return <code>true</code> on verification in an attempt to bypass a - * security check.</p> - * - * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>, - * using <i>DSA</i> and <i>SHA-1</i>. The algorithm is specified using the same - * convention as that for signatures. The <i>DSA</i> algorithm using the - * <i>SHA-1</i> message digest algorithm can be specified, for example, as - * <code>"SHA/DSA"</code> or <code>"SHA-1/DSA"</code> (they are equivalent). In - * the case of <i>RSA</i>, there are multiple choices for the message digest - * algorithm, so the signing algorithm could be specified as, for example, - * <code>"MD2/RSA"</code>, <code>"MD5/RSA"</code> or <code>"SHA-1/RSA"</code>. - * The algorithm name must be specified, as there is no default.</p> - * - * <p>The name of the Cryptography Package Provider is designated also by the - * {@link Signature} parameter to the <code>constructor</code> and the <code> - * verify()</code> method. If the provider is not specified, the default - * provider is used. Each installation can be configured to use a particular - * provider as default.</p> - * - * <p>Potential applications of <code>SignedObject</code> include:</p> - * - * <ul> - * <li>It can be used internally to any Java runtime as an unforgeable - * authorization token -- one that can be passed around without the fear that - * the token can be maliciously modified without being detected.</li> - * <li>It can be used to sign and serialize data/object for storage outside the - * Java runtime (e.g., storing critical access control data on disk).</li> - * <li>Nested <i>SignedObjects</i> can be used to construct a logical sequence - * of signatures, resembling a chain of authorization and delegation.</li> - * </ul> + * <code>SignedObject</code> is used for storing runtime objects whose + * integrity cannot be compromised without being detected. + * + * <p><code>SignedObject</code> contains a {@link Serializable} object which is + * yet to be signed and a digital signature of that object.</p> + * + * <p>The signed copy is a "deep copy" (in serialized form) of an original + * object. Any changes to that original instance are not reflected in the + * enclosed copy inside this <code>SignedObject</code>.</p> + * + * <p>Several things to note are that, first there is no need to initialize the + * signature engine as this class will handle that automatically. Second, + * verification will only succeed if the public key corresponds to the private + * key used to generate the digital signature inside this + * <code>SignedObject</code>.</p> + * + * <p>For fexibility, the signature engine can be specified in the constructor + * or the <code>verify()</code> method. Programmers wishing to verify + * <code>SignedObject</code>s should be aware of the {@link Signature} engine + * they use. A malicious or flawed {@link Signature} implementation may always + * return true on verification thus circumventing the intended secrity check + * provided by the <code>SignedObject</code>.</p> + * + * <p>The GNU security provider offers an implementation of the standard NIST + * DSA which uses "DSA" and "SHA-1". It can be specified by "SHA/DSA", + * "SHA-1/DSA" or its OID. If the RSA signature algorithm is provided then it + * could be "MD2/RSA". "MD5/RSA", or "SHA-1/RSA". The algorithm must be + * specified because there is no default.</p> * * @author Mark Benvenuto (ivymccough@worldnet.att.net) * @since 1.2 @@ -139,16 +91,22 @@ public final class SignedObject implements Serializable private String thealgorithm; /** - * Constructs a <code>SignedObject</code> from any {@link Serializable} - * object. The given object is signed with the given signing key, using the - * designated signature engine. - * - * @param object the object to be signed. - * @param signingKey the private key for signing. - * @param signingEngine the signature signing engine. - * @throws IOException if an error occurs during serialization. - * @throws InvalidKeyException if the key is invalid. - * @throws SignatureException if signing fails. + * Constructs a new instance of <code>SignedObject</code> from a + * {@link Serializable} object. The object is signed with a designated + * private key and a signature engine. + * + * @param object + * the object to sign. + * @param signingKey + * the key to use. + * @param signingEngine + * the signature engine to use. + * @throws IOException + * if a serialization error occurred. + * @throws InvalidKeyException + * if the key is invalid. + * @throws SignatureException + * if a signing error occurs. */ public SignedObject(Serializable object, PrivateKey signingKey, Signature signingEngine) @@ -170,12 +128,14 @@ public final class SignedObject implements Serializable } /** - * Retrieves the encapsulated object. The encapsulated object is de-serialized - * before it is returned. - * + * Returns the encapsulated object. The object is de-serialized before being + * returned. + * * @return the encapsulated object. - * @throws IOException if an error occurs during de-serialization. - * @throws ClassNotFoundException if an error occurs during de-serialization. + * @throws IOException + * if a de-serialization error occurs. + * @throws ClassNotFoundException + * if the encapsulated object's class was not found. */ public Object getObject() throws IOException, ClassNotFoundException { @@ -189,9 +149,9 @@ public final class SignedObject implements Serializable } /** - * Retrieves the signature on the signed object, in the form of a byte array. - * - * @return a copy of the signature. + * Returns the signature bytes of the encapsulated object. + * + * @return the signature bytes of the encapsulated object. */ public byte[] getSignature() { @@ -200,9 +160,9 @@ public final class SignedObject implements Serializable } /** - * Retrieves the name of the signature algorithm. - * - * @return the signature algorithm name. + * Returns the name of the signature algorithm. + * + * @return the name of the signature algorithm. */ public String getAlgorithm() { @@ -210,16 +170,19 @@ public final class SignedObject implements Serializable } /** - * Verifies that the signature in this <code>SignedObject</code> is the valid - * signature for the object stored inside, with the given verification key, - * using the designated verification engine. - * - * @param verificationKey the public key for verification. - * @param verificationEngine the signature verification engine. - * @return <code>true</code> if the signature is valid, <code>false</code> - * otherwise. - * @throws SignatureException if signature verification failed. - * @throws InvalidKeyException if the verification key is invalid. + * Verifies the encapsulated digital signature by checking that it was + * generated by the owner of a designated public key. + * + * @param verificationKey + * the public key to use. + * @param verificationEngine + * the signature engine to use. + * @return <code>true</code> if signature is correct, <code>false</code> + * otherwise. + * @throws InvalidKeyException + * if the key is invalid. + * @throws SignatureException + * if verification fails. */ public boolean verify(PublicKey verificationKey, Signature verificationEngine) throws InvalidKeyException, SignatureException diff --git a/libjava/classpath/java/security/Signer.java b/libjava/classpath/java/security/Signer.java index ae1463db84c..c7780f6d3aa 100644 --- a/libjava/classpath/java/security/Signer.java +++ b/libjava/classpath/java/security/Signer.java @@ -38,35 +38,29 @@ exception statement from your version. */ package java.security; /** - * <p>This class is used to represent an {@link Identity} that can also - * digitally sign data.</p> - * - * <p>The management of a signer's private keys is an important and sensitive - * issue that should be handled by subclasses as appropriate to their intended - * use.</p> + * <code>Signer</code> is a subclass of {@link Identity}. It is used to store a + * digital signature key with an <i>Identity</i>. * * @author Mark Benvenuto (ivymccough@worldnet.att.net) - * @deprecated This class is no longer used. Its functionality has been replaced - * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code> - * package, and <code>java.security.Principal</code>. + * @deprecated Replaced by <code>java.security.KeyStore</code>, the + * <code>java.security.cert</code> package, and <code>java.security.Principal</code>. */ public abstract class Signer extends Identity { private static final long serialVersionUID = -1763464102261361480L; private PrivateKey privateKey = null; - /** - * Creates a <code>Signer</code>. This constructor should only be used for - * serialization. - */ + /** Trivial constructor for serialization purposes. */ protected Signer() { } /** - * Creates a <code>Signer</code> with the specified identity name. - * - * @param name the identity name. + * Constructs a new instance of <code>Signer</code> with the specified + * identity name. + * + * @param name + * the name of the identity to use. */ public Signer(String name) { @@ -74,12 +68,16 @@ public abstract class Signer extends Identity } /** - * Creates a <code>Signer</code> with the specified identity name and scope. - * - * @param name the identity name. - * @param scope the scope of the identity. - * @throws KeyManagementException if there is already an identity with the - * same name in the scope. + * Constructs a new instance of <code>Signer</code> with the specified + * identity name and {@link IdentityScope}. + * + * @param name + * the name of the the identity to use. + * @param scope + * the {@link IdentityScope} to use. + * @throws KeyManagementException + * if a duplicate identity <code>name</code> exists within + * <code>scope</code>. */ public Signer(String name, IdentityScope scope) throws KeyManagementException { @@ -87,18 +85,12 @@ public abstract class Signer extends Identity } /** - * <p>Returns this signer's private key.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"getSignerPrivateKey"</code> as its - * argument to see if it's ok to return the private key.</p> - * - * @return this signer's private key, or <code>null</code> if the private key - * has not yet been set. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow returning the - * private key. - * @see SecurityManager#checkSecurityAccess(String) + * Returns the private key of this <code>Signer</code>. + * + * @returns the private key of this <code>Signer</code>. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public PrivateKey getPrivateKey() { @@ -110,20 +102,17 @@ public abstract class Signer extends Identity } /** - * <p>Sets the key pair (public key and private key) for this signer.</p> - * - * <p>First, if there is a security manager, its <code>checkSecurityAccess() - * </code> method is called with <code>"setSignerKeyPair"</code> as its - * argument to see if it's ok to set the key pair.</p> - * - * @param pair an initialized key pair. - * @throws InvalidParameterException if the key pair is not properly - * initialized. - * @throws KeyException if the key pair cannot be set for any other reason. - * @throws SecurityException if a security manager exists and its - * <code>checkSecurityAccess()</code> method doesn't allow setting the key - * pair. - * @see SecurityManager#checkSecurityAccess(String) + * Specifies the {@link KeyPair} associated with this <code>Signer</code>. + * + * @param pair + * the {@link KeyPair} to use. + * @throws InvalidParameterException + * if the key-pair is invalid. + * @throws KeyException + * if any another key-related error occurs. + * @throws SecurityException + * if a {@link SecurityManager} is installed which disallows this + * operation. */ public final void setKeyPair(KeyPair pair) throws InvalidParameterException, KeyException @@ -151,12 +140,7 @@ public abstract class Signer extends Identity throw new InvalidParameterException(); } - /** - * Returns a string of information about the signer. - * - * @return a string of information about the signer. - * @see SecurityManager#checkSecurityAccess(String) - */ + /** @returns a string representing this <code>Signer</code>. */ public String toString() { return (getName() + ": " + privateKey); diff --git a/libjava/classpath/java/security/cert/CRLException.java b/libjava/classpath/java/security/cert/CRLException.java index f3addfe9594..10171c418bf 100644 --- a/libjava/classpath/java/security/cert/CRLException.java +++ b/libjava/classpath/java/security/cert/CRLException.java @@ -1,5 +1,5 @@ /* CRLException.java -- Certificate Revocation List Exception - Copyright (C) 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,7 +45,7 @@ import java.security.GeneralSecurityException; * * @author Mark Benvenuto * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class CRLException extends GeneralSecurityException { @@ -70,4 +70,26 @@ public class CRLException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public CRLException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public CRLException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/cert/CertificateEncodingException.java b/libjava/classpath/java/security/cert/CertificateEncodingException.java index 0bb0c26d358..3f871691d1b 100644 --- a/libjava/classpath/java/security/cert/CertificateEncodingException.java +++ b/libjava/classpath/java/security/cert/CertificateEncodingException.java @@ -1,5 +1,5 @@ /* CertificateEncodingException.java -- Certificate Encoding Exception - Copyright (C) 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,7 +43,7 @@ package java.security.cert; * * @author Mark Benvenuto * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class CertificateEncodingException extends CertificateException { @@ -68,4 +68,26 @@ public class CertificateEncodingException extends CertificateException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public CertificateEncodingException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public CertificateEncodingException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/cert/CertificateException.java b/libjava/classpath/java/security/cert/CertificateException.java index 3e075ddaf35..8a6f383bb96 100644 --- a/libjava/classpath/java/security/cert/CertificateException.java +++ b/libjava/classpath/java/security/cert/CertificateException.java @@ -1,5 +1,5 @@ /* CertificateException.java -- Certificate Exception - Copyright (C) 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,7 +46,7 @@ import java.security.GeneralSecurityException; * @author Mark Benvenuto * @see Certificate * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class CertificateException extends GeneralSecurityException { @@ -71,4 +71,26 @@ public class CertificateException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public CertificateException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public CertificateException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/cert/CertificateParsingException.java b/libjava/classpath/java/security/cert/CertificateParsingException.java index 61faa44386e..5a930f41bfc 100644 --- a/libjava/classpath/java/security/cert/CertificateParsingException.java +++ b/libjava/classpath/java/security/cert/CertificateParsingException.java @@ -1,5 +1,5 @@ /* CertificateParsingException.java -- Certificate Parsing Exception - Copyright (C) 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,7 +43,7 @@ package java.security.cert; * * @author Mark Benvenuto * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class CertificateParsingException extends CertificateException { @@ -68,4 +68,26 @@ public class CertificateParsingException extends CertificateException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public CertificateParsingException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public CertificateParsingException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/libjava/classpath/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java index d80b962d012..da7d7479d88 100644 --- a/libjava/classpath/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java +++ b/libjava/classpath/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java @@ -54,6 +54,7 @@ public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey { // Constants // -------------------------------------------------------------------------- + long serialVersionUID = 618058533534628008L; // Methods @@ -67,45 +68,45 @@ public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey BigInteger getPublicExponent(); /** - * Returns the primeP. + * Returns the prime p. * - * @return the primeP. + * @return the prime p. */ BigInteger getPrimeP(); /** - * Returns the primeQ. + * Returns the prime q. * - * @return the primeQ. + * @return the prime q. */ BigInteger getPrimeQ(); /** - * Returns the primeExponentP. + * Returns the prime's exponent p. * - * @return the primeExponentP. + * @return the prime's exponent p. */ BigInteger getPrimeExponentP(); /** - * Returns the primeExponentQ. + * Returns the prime's exponent q. * - * @return the primeExponentQ. + * @return the prime's exponent q. */ BigInteger getPrimeExponentQ(); /** - * Returns the crtCoefficient. + * Returns the CRT Coefficient. * - * @return the crtCoefficient. + * @return the CRT Coefficient. */ BigInteger getCrtCoefficient(); /** - * Returns the otherPrimeInfo or <code>null</code> if there are only two - * prime factors (p and q). + * Returns the <i>OtherPrimeInfo</i> triplet MPIs or <code>null</code> if + * there are only two known prime factors (p and q). * - * @return the otherPrimeInfo. + * @return the <i>OtherPrimeInfo</i> INTEGERs. */ RSAOtherPrimeInfo[] getOtherPrimeInfo(); } diff --git a/libjava/classpath/java/security/spec/InvalidKeySpecException.java b/libjava/classpath/java/security/spec/InvalidKeySpecException.java index c2ec6b03b5a..bbbbcc6d720 100644 --- a/libjava/classpath/java/security/spec/InvalidKeySpecException.java +++ b/libjava/classpath/java/security/spec/InvalidKeySpecException.java @@ -1,5 +1,5 @@ /* InvalidKeySpecException.java -- invalid KeySpec Exception - Copyright (C) 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,7 +46,7 @@ import java.security.GeneralSecurityException; * @author Mark Benvenuto * @see KeySpec * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class InvalidKeySpecException extends GeneralSecurityException { @@ -71,4 +71,26 @@ public class InvalidKeySpecException extends GeneralSecurityException { super(msg); } + + /** + * Create a new instance with a descriptive error message and + * a cause. + * @param s the descriptive error message + * @param cause the cause + * @since 1.5 + */ + public InvalidKeySpecException(String s, Throwable cause) + { + super(s, cause); + } + + /** + * Create a new instance with a cause. + * @param cause the cause + * @since 1.5 + */ + public InvalidKeySpecException(Throwable cause) + { + super(cause); + } } diff --git a/libjava/classpath/java/security/spec/PSSParameterSpec.java b/libjava/classpath/java/security/spec/PSSParameterSpec.java index 7a14a24fbe4..f2a83d96718 100644 --- a/libjava/classpath/java/security/spec/PSSParameterSpec.java +++ b/libjava/classpath/java/security/spec/PSSParameterSpec.java @@ -38,9 +38,9 @@ exception statement from your version. */ package java.security.spec; /** - * This class specifies a parameter spec for RSA PSS encoding scheme, as - * defined in the PKCS#1 v2.1. - * + * An implementation of {@link AlgorithmParameterSpec} for the RSA PSS encoding + * scheme. + * * @since 1.4 * @see AlgorithmParameterSpec * @see java.security.Signature @@ -56,12 +56,13 @@ public class PSSParameterSpec implements AlgorithmParameterSpec // -------------------------------------------------------------------------- /** - * Creates a new <code>PSSParameterSpec</code> given the salt length as - * defined in PKCS#1. - * - * @param saltLen the length of salt in bits to be used in PKCS#1 PSS encoding. - * @throws IllegalArgumentException if <code>saltLen</code> is less than - * <code>0</code>. + * Construct a new instance of <code>PSSParameterSpec</code> given a salt + * length. + * + * @param saltLen + * the length in bits of the salt. + * @throws IllegalArgumentException + * if <code>saltLen</code> is less than <code>0</code>. */ public PSSParameterSpec(int saltLen) { @@ -78,11 +79,7 @@ public class PSSParameterSpec implements AlgorithmParameterSpec // Instance methods // -------------------------------------------------------------------------- - /** - * Returns the salt length in bits. - * - * @return the salt length. - */ + /** @return the length (in bits) of the salt. */ public int getSaltLength() { return this.saltLen; diff --git a/libjava/classpath/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/libjava/classpath/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java index 519a0291373..9e8ad0da776 100644 --- a/libjava/classpath/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java +++ b/libjava/classpath/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java @@ -40,9 +40,9 @@ package java.security.spec; import java.math.BigInteger; /** - * This class specifies an RSA multi-prime private key, as defined in the + * This class represents an RSA multi-prime private key, as defined in the * PKCS#1 v2.1, using the <i>Chinese Remainder Theorem</i> (CRT) information - * values for efficiency. + * values. * * @since 1.4 * @see java.security.Key @@ -70,29 +70,35 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec // -------------------------------------------------------------------------- /** - * <p>Creates a new <code>RSAMultiPrimePrivateCrtKeySpec</code> given the - * modulus, publicExponent, privateExponent, primeP, primeQ, primeExponentP, - * primeExponentQ, crtCoefficient, and otherPrimeInfo as defined in PKCS#1 - * v2.1.</p> - * + * Constructs a new instance of <code>RSAMultiPrimePrivateCrtKeySpec</code> + * given the various PKCS#1 v2.1 parameters. + * * <p>Note that <code>otherPrimeInfo</code> is cloned when constructing this * object.</p> - * - * @param modulus the modulus n. - * @param publicExponent the public exponent e. - * @param privateExponent the private exponent d. - * @param primeP the prime factor p of n. - * @param primeQ the prime factor q of n. - * @param primeExponentP this is d mod (p-1). - * @param primeExponentQ this is d mod (q-1). - * @param crtCoefficient the Chinese Remainder Theorem coefficient q-1 mod p. - * @param otherPrimeInfo triplets of the rest of primes, <code>null</code> - * can be specified if there are only two prime factors (p and q). - * @throws NullPointerException if any of the parameters, i.e. modulus, - * publicExponent, privateExponent, primeP, primeQ, primeExponentP, - * primeExponentQ, crtCoefficient, is <code>null</code>. - * @throws IllegalArgumentException if an empty, i.e. 0-length, - * otherPrimeInfo is specified. + * + * @param modulus + * the modulus n. + * @param publicExponent + * the public exponent e. + * @param privateExponent + * the private exponent d. + * @param primeP + * the prime factor p of n. + * @param primeQ + * the prime factor q of n. + * @param primeExponentP + * this is d mod (p-1). + * @param primeExponentQ + * this is d mod (q-1). + * @param crtCoefficient + * the Chinese Remainder Theorem coefficient q-1 mod p. + * @param otherPrimeInfo + * triplets of the rest of primes, <code>null</code> can be + * specified if there are only two prime factors (p and q). + * @throws NullPointerException + * if any of the parameters is <code>null</code>. + * @throws IllegalArgumentException + * if an empty <code>otherPrimeInfo</code> is specified. */ public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus, BigInteger publicExponent, @@ -153,9 +159,9 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec } /** - * Returns the primeP. + * Returns the prime p. * - * @return the primeP. + * @return the prime p. */ public BigInteger getPrimeP() { @@ -163,9 +169,9 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec } /** - * Returns the primeQ. + * Returns the prime q. * - * @return the primeQ. + * @return the prime q. */ public BigInteger getPrimeQ() { @@ -173,9 +179,9 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec } /** - * Returns the primeExponentP. + * Returns d mod (p-1). * - * @return the primeExponentP. + * @return d mod (p-1). */ public BigInteger getPrimeExponentP() { @@ -183,9 +189,9 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec } /** - * Returns the primeExponentQ. + * Returns d mod (q-1). * - * @return the primeExponentQ. + * @return d mod (q-1). */ public BigInteger getPrimeExponentQ() { @@ -193,9 +199,9 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec } /** - * Returns the crtCoefficient. + * Returns the CRT Coefficient q-1 mod p. * - * @return the crtCoefficient. + * @return the CRT Coefficient q-1 mod p. */ public BigInteger getCrtCoefficient() { @@ -203,10 +209,10 @@ public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec } /** - * Returns a copy of the otherPrimeInfo or <code>null</code> if there are - * only two prime factors (p and q). + * Returns a clone of <code>otherPrimeInfo</code> or <code>null</code> if + * it was <code>null</code> at construction time. * - * @return the otherPrimeInfo. + * @return a cloned copy of <code>otherPrimeInfo</code>. */ public RSAOtherPrimeInfo[] getOtherPrimeInfo() { diff --git a/libjava/classpath/java/security/spec/RSAOtherPrimeInfo.java b/libjava/classpath/java/security/spec/RSAOtherPrimeInfo.java index 654bcb574d8..03cdca227ed 100644 --- a/libjava/classpath/java/security/spec/RSAOtherPrimeInfo.java +++ b/libjava/classpath/java/security/spec/RSAOtherPrimeInfo.java @@ -40,17 +40,8 @@ package java.security.spec; import java.math.BigInteger; /** - * This class represents the triplet (prime, exponent, and coefficient) inside - * RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1. The ASN.1 - * syntax of RSA's OtherPrimeInfo is as follows: - * - * <pre> - * OtherPrimeInfo ::= SEQUENCE { - * prime INTEGER, - * exponent INTEGER, - * coefficient INTEGER - * } - * </pre> + * An in-memory representation of the RSA triplet (prime, exponent, and + * coefficient) inside a PKCS#1 v2.1 <i>OtherPrimeInfo</i> structure. * * @since 1.4 * @see RSAPrivateCrtKeySpec @@ -69,14 +60,16 @@ public class RSAOtherPrimeInfo // -------------------------------------------------------------------------- /** - * Creates a new <code>RSAOtherPrimeInfo</code> given the prime, - * primeExponent, and crtCoefficient as defined in PKCS#1. - * - * @param prime the prime factor of n. - * @param primeExponent the exponent. - * @param crtCoefficient the Chinese Remainder Theorem coefficient. - * @throws NullPointerException if any of the parameters, i.e. prime, - * primeExponent, crtCoefficient, is <code>null</code>. + * Constructs a new <code>RSAOtherPrimeInfo</code> given the PKCS#1 MPIs. + * + * @param prime + * the prime factor of n. + * @param primeExponent + * the exponent. + * @param crtCoefficient + * the Chinese Remainder Theorem coefficient. + * @throws NullPointerException + * if any of the parameters is <code>null</code>. */ public RSAOtherPrimeInfo(BigInteger prime, BigInteger primeExponent, BigInteger crtCoefficient) @@ -122,9 +115,9 @@ public class RSAOtherPrimeInfo } /** - * Returns the prime's crtCoefficient. + * Returns the CRT Coefficient. * - * @return the crtCoefficient. + * @return the CRT Coefficient. */ public final BigInteger getCrtCoefficient() { diff --git a/libjava/classpath/java/util/AbstractCollection.java b/libjava/classpath/java/util/AbstractCollection.java index 00ee23ebd43..3ae98e07311 100644 --- a/libjava/classpath/java/util/AbstractCollection.java +++ b/libjava/classpath/java/util/AbstractCollection.java @@ -423,7 +423,9 @@ public abstract class AbstractCollection implements Collection * of the form "[a, b, ...]" where a and b etc are the results of calling * toString on the elements of the collection. This implementation obtains an * Iterator over the Collection and adds each element to a StringBuffer as it - * is returned by the iterator. + * is returned by the iterator. "<this>" is inserted when the collection + * contains itself (only works for direct containment, not for collections + * inside collections). * * @return a String representation of the Collection */ @@ -431,10 +433,16 @@ public abstract class AbstractCollection implements Collection { Iterator itr = iterator(); StringBuffer r = new StringBuffer("["); - for (int pos = size(); pos > 0; pos--) + boolean hasNext = itr.hasNext(); + while (hasNext) { - r.append(itr.next()); - if (pos > 1) + Object o = itr.next(); + if (o == this) + r.append("<this>"); + else + r.append(o); + hasNext = itr.hasNext(); + if (hasNext) r.append(", "); } r.append("]"); diff --git a/libjava/classpath/java/util/ResourceBundle.java b/libjava/classpath/java/util/ResourceBundle.java index 6aea6731a5d..4dcb9ad16f8 100644 --- a/libjava/classpath/java/util/ResourceBundle.java +++ b/libjava/classpath/java/util/ResourceBundle.java @@ -1,5 +1,5 @@ /* ResourceBundle -- aids in loading resource bundles - Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -476,9 +476,7 @@ public abstract class ResourceBundle if (ResourceBundle.class.isAssignableFrom(rbClass)) bundle = (ResourceBundle) rbClass.newInstance(); } - catch (IllegalAccessException ex) {} - catch (InstantiationException ex) {} - catch (ClassNotFoundException ex) {} + catch (Exception ex) {} if (bundle == null) { diff --git a/libjava/classpath/java/util/jar/Attributes.java b/libjava/classpath/java/util/jar/Attributes.java index 4db2c72e75b..c8babddab37 100644 --- a/libjava/classpath/java/util/jar/Attributes.java +++ b/libjava/classpath/java/util/jar/Attributes.java @@ -427,16 +427,13 @@ public class Attributes implements Cloneable, Map * Attributes map. * When the name already exists the value is replaced and the old value * is returned. - * <p> - * I don't know why there is no public method with this signature. I think - * there should be one. * * @param name the attribite name to add/replace * @param value the (new) value of the attribute name * @returns the old value of the attribute name or null if it didn't exist * yet */ - String putValue(Name name, String value) + public String putValue(Name name, String value) { return (String) put(name, value); } diff --git a/libjava/classpath/java/util/logging/FileHandler.java b/libjava/classpath/java/util/logging/FileHandler.java index b03df97ec60..cde86191612 100644 --- a/libjava/classpath/java/util/logging/FileHandler.java +++ b/libjava/classpath/java/util/logging/FileHandler.java @@ -115,7 +115,7 @@ import java.util.ListIterator; * * <li><code>%h</code> - replaced by the location of the home * directory of the current user. This value is taken from the - * system property <code>file.separator</code>.</li> + * system property <code>user.home</code>.</li> * * <li><code>%g</code> - replaced by a generation number for * distinguisthing the individual items in the rotating set diff --git a/libjava/classpath/java/util/logging/LogManager.java b/libjava/classpath/java/util/logging/LogManager.java index b62292f7978..73eb9bcdd21 100644 --- a/libjava/classpath/java/util/logging/LogManager.java +++ b/libjava/classpath/java/util/logging/LogManager.java @@ -41,6 +41,7 @@ package java.util.logging; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; @@ -295,6 +296,28 @@ public class LogManager if (parent != logger.getParent()) logger.setParent(parent); + // The level of the newly added logger must be specified. + // The easiest case is if there is a level for exactly this logger + // in the properties. If no such level exists the level needs to be + // searched along the hirachy. So if there is a new logger 'foo.blah.blub' + // and an existing parent logger 'foo' the properties 'foo.blah.blub.level' + // and 'foo.blah.level' need to be checked. If both do not exist in the + // properties the level of the new logger is set to 'null' (i.e. it uses the + // level of its parent 'foo'). + Level logLevel = logger.getLevel(); + String searchName = name; + String parentName = parent != null ? parent.getName() : ""; + while (logLevel == null && ! searchName.equals(parentName)) + { + logLevel = getLevelProperty(searchName + ".level", logLevel); + int index = searchName.lastIndexOf('.'); + if(index > -1) + searchName = searchName.substring(0,index); + else + searchName = ""; + } + logger.setLevel(logLevel); + /* It can happen that existing loggers should be children of * the newly added logger. For example, assume that there * already exist loggers under the names "", "foo", and "foo.bar.baz". @@ -488,23 +511,37 @@ public class LogManager path = System.getProperty("java.util.logging.config.file"); if ((path == null) || (path.length() == 0)) { - String url = (System.getProperty("gnu.classpath.home.url") - + "/logging.properties"); - inputStream = new URL(url).openStream(); + String url = (System.getProperty("gnu.classpath.home.url") + + "/logging.properties"); + try + { + inputStream = new URL(url).openStream(); + } + catch (Exception e) + { + inputStream=null; + } + + // If no config file could be found use a default configuration. + if(inputStream == null) + { + String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n" + + ".level=INFO \n"; + inputStream = new ByteArrayInputStream(defaultConfig.getBytes()); + } } else inputStream = new java.io.FileInputStream(path); try { - readConfiguration(inputStream); + readConfiguration(inputStream); } finally { - /* Close the stream in order to save - * resources such as file descriptors. - */ - inputStream.close(); + // Close the stream in order to save + // resources such as file descriptors. + inputStream.close(); } } diff --git a/libjava/classpath/java/util/logging/SimpleFormatter.java b/libjava/classpath/java/util/logging/SimpleFormatter.java index ff53db8c055..2ebb1a1485f 100644 --- a/libjava/classpath/java/util/logging/SimpleFormatter.java +++ b/libjava/classpath/java/util/logging/SimpleFormatter.java @@ -39,6 +39,8 @@ exception statement from your version. */ package java.util.logging; +import java.io.PrintWriter; +import java.io.StringWriter; import java.text.DateFormat; import java.util.Date; @@ -114,6 +116,14 @@ public class SimpleFormatter buf.append(lineSep); + Throwable throwable = record.getThrown(); + if (throwable != null) + { + StringWriter sink = new StringWriter(); + throwable.printStackTrace(new PrintWriter(sink, true)); + buf.append(sink.toString()); + } + return buf.toString(); } } diff --git a/libjava/classpath/java/util/prefs/AbstractPreferences.java b/libjava/classpath/java/util/prefs/AbstractPreferences.java index 3f70400f5d1..e676dc3105c 100644 --- a/libjava/classpath/java/util/prefs/AbstractPreferences.java +++ b/libjava/classpath/java/util/prefs/AbstractPreferences.java @@ -1,5 +1,5 @@ /* AbstractPreferences -- Partial implementation of a Preference node - Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,11 +38,13 @@ exception statement from your version. */ package java.util.prefs; +import gnu.java.util.prefs.EventDispatcher; import gnu.java.util.prefs.NodeWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.TreeSet; @@ -68,7 +70,7 @@ public abstract class AbstractPreferences extends Preferences { /** * Set to true in the contructor if the node did not exist in the backing * store when this preference node object was created. Should be set in - * the contructor of a subclass. Defaults to false. Used to fire node + * the constructor of a subclass. Defaults to false. Used to fire node * changed events. */ protected boolean newNode = false; @@ -97,6 +99,16 @@ public abstract class AbstractPreferences extends Preferences { */ private HashMap childCache = new HashMap(); + /** + * A list of all the registered NodeChangeListener objects. + */ + private ArrayList nodeListeners; + + /** + * A list of all the registered PreferenceChangeListener objects. + */ + private ArrayList preferenceListeners; + // constructor /** @@ -256,7 +268,7 @@ public abstract class AbstractPreferences extends Preferences { * @exception IllegalArgumentException if the path contains two or more * consecutive '/' characters, ends with a '/' charactor and is not the * string "/" (indicating the root node) or any name on the path is more - * then 80 characters long + * than 80 characters long */ public Preferences node(String path) { synchronized(lock) { @@ -325,8 +337,9 @@ public abstract class AbstractPreferences extends Preferences { // Not in childCache yet so create a new sub node child = childSpi(childName); - // XXX - check if node is new childCache.put(childName, child); + if (child.newNode && nodeListeners != null) + fire(new NodeChangeEvent(this, child), true); } // Lock the child and go down @@ -477,9 +490,7 @@ public abstract class AbstractPreferences extends Preferences { // export methods - /** - * XXX - */ + // Inherit javadoc. public void exportNode(OutputStream os) throws BackingStoreException, IOException @@ -488,9 +499,7 @@ public abstract class AbstractPreferences extends Preferences { nodeWriter.writePrefs(); } - /** - * XXX - */ + // Inherit javadoc. public void exportSubtree(OutputStream os) throws BackingStoreException, IOException @@ -765,8 +774,8 @@ public abstract class AbstractPreferences extends Preferences { * Key and value cannot be null, the key cannot exceed 80 characters * and the value cannot exceed 8192 characters. * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. + * The result will be immediately visible in this VM, but may not be + * immediately written to the backing store. * <p> * Checks that key and value are valid, locks this node, and checks that * the node has not been removed. Then it calls <code>putSpi()</code>. @@ -789,7 +798,8 @@ public abstract class AbstractPreferences extends Preferences { putSpi(key, value); - // XXX - fire events + if (preferenceListeners != null) + fire(new PreferenceChangeEvent(this, key, value)); } } @@ -804,9 +814,7 @@ public abstract class AbstractPreferences extends Preferences { * @exception IllegalStateException when this node has been removed */ public void putBoolean(String key, boolean value) { - put(key, String.valueOf(value)); - // XXX - Use when using 1.4 compatible Boolean - // put(key, Boolean.toString(value)); + put(key, Boolean.toString(value)); } /** @@ -935,8 +943,8 @@ public abstract class AbstractPreferences extends Preferences { /** * Removes the preferences entry from this preferences node. * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. + * The result will be immediately visible in this VM, but may not be + * immediately written to the backing store. * <p> * This implementation checks that the key is not larger then 80 * characters, gets the lock of this node, checks that the node has @@ -955,6 +963,9 @@ public abstract class AbstractPreferences extends Preferences { throw new IllegalStateException("Node removed"); removeSpi(key); + + if (preferenceListeners != null) + fire(new PreferenceChangeEvent(this, key, null)); } } @@ -962,7 +973,7 @@ public abstract class AbstractPreferences extends Preferences { * Removes all entries from this preferences node. May need access to the * backing store to get and clear all entries. * <p> - * The result will be immediatly visible in this VM, but may not be + * The result will be immediately visible in this VM, but may not be * immediatly written to the backing store. * <p> * This implementation locks this node, checks that the node has not been @@ -1049,7 +1060,7 @@ public abstract class AbstractPreferences extends Preferences { for (int i = 0; i < keys.length; i++) { // Have to lock this node again to access the childCache AbstractPreferences subNode; - synchronized(this) { + synchronized(lock) { subNode = (AbstractPreferences) childCache.get(keys[i]); } @@ -1087,8 +1098,8 @@ public abstract class AbstractPreferences extends Preferences { if (parent == null) throw new UnsupportedOperationException("Cannot remove root node"); - synchronized(parent) { - synchronized(this) { + synchronized (parent.lock) { + synchronized(this.lock) { if (isRemoved()) throw new IllegalStateException("Node Removed"); @@ -1122,7 +1133,7 @@ public abstract class AbstractPreferences extends Preferences { Iterator i = childCache.values().iterator(); while (i.hasNext()) { AbstractPreferences node = (AbstractPreferences) i.next(); - synchronized(node) { + synchronized(node.lock) { node.purge(); } } @@ -1134,30 +1145,131 @@ public abstract class AbstractPreferences extends Preferences { removeNodeSpi(); removed = true; - // XXX - check for listeners + if (nodeListeners != null) + fire(new NodeChangeEvent(parent, this), false); } // listener methods /** - * XXX + * Add a listener which is notified when a sub-node of this node + * is added or removed. + * @param listener the listener to add */ - public void addNodeChangeListener(NodeChangeListener listener) { - // XXX + public void addNodeChangeListener(NodeChangeListener listener) + { + synchronized (lock) + { + if (isRemoved()) + throw new IllegalStateException("node has been removed"); + if (listener == null) + throw new NullPointerException("listener is null"); + if (nodeListeners == null) + nodeListeners = new ArrayList(); + nodeListeners.add(listener); + } } - public void addPreferenceChangeListener(PreferenceChangeListener listener) { - // XXX + /** + * Add a listener which is notified when a value in this node + * is added, changed, or removed. + * @param listener the listener to add + */ + public void addPreferenceChangeListener(PreferenceChangeListener listener) + { + synchronized (lock) + { + if (isRemoved()) + throw new IllegalStateException("node has been removed"); + if (listener == null) + throw new NullPointerException("listener is null"); + if (preferenceListeners == null) + preferenceListeners = new ArrayList(); + preferenceListeners.add(listener); + } } - public void removeNodeChangeListener(NodeChangeListener listener) { - // XXX + /** + * Remove the indicated node change listener from the list of + * listeners to notify. + * @param listener the listener to remove + */ + public void removeNodeChangeListener(NodeChangeListener listener) + { + synchronized (lock) + { + if (isRemoved()) + throw new IllegalStateException("node has been removed"); + if (listener == null) + throw new NullPointerException("listener is null"); + if (nodeListeners != null) + nodeListeners.remove(listener); + } } - public void removePreferenceChangeListener - (PreferenceChangeListener listener) + /** + * Remove the indicated preference change listener from the list of + * listeners to notify. + * @param listener the listener to remove + */ + public void removePreferenceChangeListener (PreferenceChangeListener listener) { - // XXX + synchronized (lock) + { + if (isRemoved()) + throw new IllegalStateException("node has been removed"); + if (listener == null) + throw new NullPointerException("listener is null"); + if (preferenceListeners != null) + preferenceListeners.remove(listener); + } + } + + /** + * Send a preference change event to all listeners. Note that + * the caller is responsible for holding the node's lock, and + * for checking that the list of listeners is not null. + * @param event the event to send + */ + private void fire(final PreferenceChangeEvent event) + { + Iterator it = preferenceListeners.iterator(); + while (it.hasNext()) + { + final PreferenceChangeListener l = (PreferenceChangeListener) it.next(); + EventDispatcher.dispatch(new Runnable() + { + public void run() + { + l.preferenceChange(event); + } + }); + } + } + + /** + * Send a node change event to all listeners. Note that + * the caller is responsible for holding the node's lock, and + * for checking that the list of listeners is not null. + * @param event the event to send + */ + private void fire(final NodeChangeEvent event, final boolean added) + { + Iterator it = nodeListeners.iterator(); + while (it.hasNext()) + { + final NodeChangeListener l = (NodeChangeListener) it.next(); + EventDispatcher.dispatch(new Runnable() + { + public void run() + { + if (added) + l.childAdded(event); + else + l.childRemoved(event); + } + }); + } } // abstract spi methods @@ -1214,7 +1326,7 @@ public abstract class AbstractPreferences extends Preferences { /** * Sets the value of the given preferences entry for this node. * The implementation is not required to propagate the change to the - * backing store immediatly. It may not throw an exception when it tries + * backing store immediately. It may not throw an exception when it tries * to write to the backing store and that operation fails, the failure * should be registered so a later invocation of <code>flush()</code> * or <code>sync()</code> can signal the failure. @@ -1227,7 +1339,7 @@ public abstract class AbstractPreferences extends Preferences { /** * Removes the given key entry from this preferences node. * The implementation is not required to propagate the change to the - * backing store immediatly. It may not throw an exception when it tries + * backing store immediately. It may not throw an exception when it tries * to write to the backing store and that operation fails, the failure * should be registered so a later invocation of <code>flush()</code> * or <code>sync()</code> can signal the failure. diff --git a/libjava/classpath/java/util/prefs/NodeChangeEvent.java b/libjava/classpath/java/util/prefs/NodeChangeEvent.java index 89986db88b3..8c48fb29f9e 100644 --- a/libjava/classpath/java/util/prefs/NodeChangeEvent.java +++ b/libjava/classpath/java/util/prefs/NodeChangeEvent.java @@ -1,5 +1,5 @@ /* NodeChangeEvent - ObjectEvent fired when a Preference node is added/removed - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,6 +37,10 @@ exception statement from your version. */ package java.util.prefs; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.EventObject; /** @@ -44,12 +48,16 @@ import java.util.EventObject; * This event is only generated when a new subnode is added or a subnode is * removed from a preference node. Changes in the entries of a preference node * are indicated with a <code>PreferenceChangeEvent</code>. + * <p> + * Note that although this class is marked as serializable, attempts to + * serialize it will fail with NotSerializableException. * * @since 1.4 * @author Mark Wielaard (mark@klomp.org) */ public class NodeChangeEvent extends EventObject { + // We have this to placate the compiler. private static final long serialVersionUID =8068949086596572957L; /** @@ -88,4 +96,16 @@ public class NodeChangeEvent extends EventObject { public Preferences getChild() { return child; } + + private void readObject(ObjectInputStream ois) + throws IOException + { + throw new NotSerializableException("LineEvent is not serializable"); + } + + private void writeObject(ObjectOutputStream oos) + throws IOException + { + throw new NotSerializableException("LineEvent is not serializable"); + } } diff --git a/libjava/classpath/java/util/prefs/PreferenceChangeEvent.java b/libjava/classpath/java/util/prefs/PreferenceChangeEvent.java index fe371f15e4e..41c3a478c71 100644 --- a/libjava/classpath/java/util/prefs/PreferenceChangeEvent.java +++ b/libjava/classpath/java/util/prefs/PreferenceChangeEvent.java @@ -1,5 +1,5 @@ /* PreferenceChangeEvent - ObjectEvent fired when a Preferences entry changes - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,6 +37,10 @@ exception statement from your version. */ package java.util.prefs; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.EventObject; /** @@ -47,12 +51,16 @@ import java.util.EventObject; * Preference change events are only generated for entries in one particular * preference node. Notification of subnode addition/removal is given by a * <code>NodeChangeEvent</code>. + * <p> + * Note that although this class is marked as serializable, attempts to + * serialize it will fail with NotSerializableException. * * @since 1.4 * @author Mark Wielaard (mark@klomp.org) */ public class PreferenceChangeEvent extends EventObject { + // We have this to placate the compiler. private static final long serialVersionUID = 793724513368024975L; /** @@ -102,4 +110,16 @@ public class PreferenceChangeEvent extends EventObject { public String getNewValue() { return newValue; } + + private void readObject(ObjectInputStream ois) + throws IOException + { + throw new NotSerializableException("LineEvent is not serializable"); + } + + private void writeObject(ObjectOutputStream oos) + throws IOException + { + throw new NotSerializableException("LineEvent is not serializable"); + } } diff --git a/libjava/classpath/java/util/prefs/Preferences.java b/libjava/classpath/java/util/prefs/Preferences.java index 3fee1c5da74..a78381bfa1e 100644 --- a/libjava/classpath/java/util/prefs/Preferences.java +++ b/libjava/classpath/java/util/prefs/Preferences.java @@ -1,5 +1,5 @@ /* Preferences -- Preference node containing key value entries and subnodes - Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -90,12 +90,9 @@ public abstract class Preferences { /** * Default PreferencesFactory class used when the system property * "java.util.prefs.PreferencesFactory" is not set. - * <p> - * XXX - Currently set to MemoryBasedFactory, should be changed - * when FileBasedPreferences backend works. */ private static final String defaultFactoryClass - = "gnu.java.util.prefs.MemoryBasedFactory"; + = "gnu.java.util.prefs.FileBasedFactory"; /** Permission needed to access system or user root. */ private static final Permission prefsPermission @@ -219,8 +216,7 @@ public abstract class Preferences { catch (Exception e) { throw new RuntimeException ("Couldn't load default factory" - + " '"+ defaultFactoryClass +"'"); - // XXX - when using 1.4 compatible throwables add cause + + " '"+ defaultFactoryClass +"'", e); } } @@ -288,7 +284,13 @@ public abstract class Preferences { } /** - * XXX + * Import preferences from the given input stream. This expects + * preferences to be represented in XML as emitted by + * {@link #exportNode(OutputStream)} and + * {@link #exportSubtree(OutputStream)}. + * @throws IOException if there is an error while reading + * @throws InvalidPreferencesFormatException if the XML is not properly + * formatted */ public static void importPreferences(InputStream is) throws InvalidPreferencesFormatException, @@ -385,14 +387,28 @@ public abstract class Preferences { // abstract methods (export) /** - * XXX + * Export this node, but not its descendants, as XML to the + * indicated output stream. The XML will be encoded using UTF-8 + * and will use a specified document type:<br> + * <code><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"></code><br> + * @param os the output stream to which the XML is sent + * @throws BackingStoreException if preference data cannot be read + * @throws IOException if an error occurs while writing the XML + * @throws IllegalStateException if this node or an ancestor has been removed */ public abstract void exportNode(OutputStream os) throws BackingStoreException, IOException; /** - * XXX + * Export this node and all its descendants as XML to the + * indicated output stream. The XML will be encoded using UTF-8 + * and will use a specified document type:<br> + * <code><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"></code><br> + * @param os the output stream to which the XML is sent + * @throws BackingStoreException if preference data cannot be read + * @throws IOException if an error occurs while writing the XML + * @throws IllegalStateException if this node or an ancestor has been removed */ public abstract void exportSubtree(OutputStream os) throws BackingStoreException, diff --git a/libjava/classpath/java/util/regex/MatchResult.java b/libjava/classpath/java/util/regex/MatchResult.java new file mode 100644 index 00000000000..c82d8cc9963 --- /dev/null +++ b/libjava/classpath/java/util/regex/MatchResult.java @@ -0,0 +1,81 @@ +/* MatchResult.java -- Result of a regular expression match. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util.regex; + +/** + * This interface represents the result of a regular expression match. + * It can be used to query the contents of the match, but not to modify + * them. + * @since 1.5 + */ +public interface MatchResult +{ + /** Returns the index just after the last matched character. */ + int end(); + + /** + * Returns the index just after the last matched character of the + * given sub-match group. + * @param group the sub-match group + */ + int end(int group); + + /** Returns the substring of the input which was matched. */ + String group(); + + /** + * Returns the substring of the input which was matched by the + * given sub-match group. + * @param group the sub-match group + */ + String group(int group); + + /** Returns the number of sub-match groups in the matching pattern. */ + int groupCount(); + + /** Returns the index of the first character of the match. */ + int start(); + + /** + * Returns the index of the first character of the given sub-match + * group. + * @param group the sub-match group + */ + int start(int group); +} diff --git a/libjava/classpath/java/util/regex/Matcher.java b/libjava/classpath/java/util/regex/Matcher.java index 5d04bdbfc2f..98086bfdbe7 100644 --- a/libjava/classpath/java/util/regex/Matcher.java +++ b/libjava/classpath/java/util/regex/Matcher.java @@ -1,5 +1,5 @@ /* Matcher.java -- Instance of a regular expression applied to a char sequence. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,7 @@ exception statement from your version. */ package java.util.regex; +import gnu.regexp.RE; import gnu.regexp.REMatch; /** @@ -45,7 +46,7 @@ import gnu.regexp.REMatch; * * @since 1.4 */ -public final class Matcher +public final class Matcher implements MatchResult { private Pattern pattern; private CharSequence input; @@ -74,7 +75,8 @@ public final class Matcher assertMatchOp(); sb.append(input.subSequence(appendPosition, match.getStartIndex()).toString()); - sb.append(match.substituteInto(replacement)); + sb.append(RE.getReplacement(replacement, match, + RE.REG_REPLACE_USE_BACKSLASHESCAPE)); appendPosition = match.getEndIndex(); return this; } @@ -189,7 +191,8 @@ public final class Matcher { reset(); // Semantics might not quite match - return pattern.getRE().substitute(input, replacement, position); + return pattern.getRE().substitute(input, replacement, position, + RE.REG_REPLACE_USE_BACKSLASHESCAPE); } /** @@ -198,7 +201,8 @@ public final class Matcher public String replaceAll (String replacement) { reset(); - return pattern.getRE().substituteAll(input, replacement, position); + return pattern.getRE().substituteAll(input, replacement, position, + RE.REG_REPLACE_USE_BACKSLASHESCAPE); } public int groupCount () @@ -233,10 +237,15 @@ public final class Matcher */ public boolean matches () { - if (lookingAt()) + match = pattern.getRE().getMatch(input, 0, RE.REG_TRY_ENTIRE_MATCH); + if (match != null) { - if (position == input.length()) - return true; + if (match.getStartIndex() == 0) + { + position = match.getEndIndex(); + if (position == input.length()) + return true; + } match = null; } return false; diff --git a/libjava/classpath/java/util/regex/PatternSyntaxException.java b/libjava/classpath/java/util/regex/PatternSyntaxException.java index 0c80e119c37..41e650d324b 100644 --- a/libjava/classpath/java/util/regex/PatternSyntaxException.java +++ b/libjava/classpath/java/util/regex/PatternSyntaxException.java @@ -41,6 +41,7 @@ package java.util.regex; * Indicates illegal pattern for regular expression. * Includes state to inspect the pattern and what and where the expression * was not valid regular expression. + * @since 1.4 */ public class PatternSyntaxException extends IllegalArgumentException { diff --git a/libjava/classpath/java/util/zip/ZipConstants.java b/libjava/classpath/java/util/zip/ZipConstants.java index 952a44def4c..6d664196a53 100644 --- a/libjava/classpath/java/util/zip/ZipConstants.java +++ b/libjava/classpath/java/util/zip/ZipConstants.java @@ -1,5 +1,5 @@ /* java.util.zip.ZipConstants - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,7 @@ interface ZipConstants { /* The local file header */ int LOCHDR = 30; - int LOCSIG = 'P'|('K'<<8)|(3<<16)|(4<<24); + long LOCSIG = 'P'|('K'<<8)|(3<<16)|(4<<24); int LOCVER = 4; int LOCFLG = 6; @@ -54,7 +54,7 @@ interface ZipConstants int LOCEXT = 28; /* The Data descriptor */ - int EXTSIG = 'P'|('K'<<8)|(7<<16)|(8<<24); + long EXTSIG = 'P'|('K'<<8)|(7<<16)|(8<<24); int EXTHDR = 16; int EXTCRC = 4; @@ -62,7 +62,7 @@ interface ZipConstants int EXTLEN = 12; /* The central directory file header */ - int CENSIG = 'P'|('K'<<8)|(1<<16)|(2<<24); + long CENSIG = 'P'|('K'<<8)|(1<<16)|(2<<24); int CENHDR = 46; int CENVEM = 4; @@ -82,7 +82,7 @@ interface ZipConstants int CENOFF = 42; /* The entries in the end of central directory */ - int ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24); + long ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24); int ENDHDR = 22; /* The following two fields are missing in SUN JDK */ diff --git a/libjava/classpath/java/util/zip/ZipFile.java b/libjava/classpath/java/util/zip/ZipFile.java index 4be845ea781..7307ee9a422 100644 --- a/libjava/classpath/java/util/zip/ZipFile.java +++ b/libjava/classpath/java/util/zip/ZipFile.java @@ -1,5 +1,5 @@ /* ZipFile.java -- - Copyright (C) 2001, 2002, 2003, 2004, 2005 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,8 +41,6 @@ package java.util.zip; import gnu.java.util.EmptyEnumeration; -import java.io.BufferedInputStream; -import java.io.DataInput; import java.io.EOFException; import java.io.File; import java.io.IOException; @@ -141,23 +139,33 @@ public class ZipFile implements ZipConstants checkZipFile(); } - private void checkZipFile() throws IOException, ZipException + private void checkZipFile() throws ZipException { - byte[] magicBuf = new byte[4]; - boolean validRead = true; + boolean valid = false; try { - raf.readFully(magicBuf); - } - catch (EOFException eof) + byte[] buf = new byte[4]; + raf.readFully(buf); + int sig = buf[0] & 0xFF + | ((buf[1] & 0xFF) << 8) + | ((buf[2] & 0xFF) << 16) + | ((buf[3] & 0xFF) << 24); + valid = sig == LOCSIG; + } + catch (IOException _) { - validRead = false; } - if (validRead == false || readLeInt(magicBuf, 0) != LOCSIG) + if (!valid) { - raf.close(); + try + { + raf.close(); + } + catch (IOException _) + { + } throw new ZipException("Not a valid zip file"); } } @@ -172,69 +180,6 @@ public class ZipFile implements ZipConstants } /** - * Read an unsigned short in little endian byte order from the given - * DataInput stream using the given byte buffer. - * - * @param di DataInput stream to read from. - * @param b the byte buffer to read in (must be at least 2 bytes long). - * @return The value read. - * - * @exception IOException if a i/o error occured. - * @exception EOFException if the file ends prematurely - */ - private int readLeShort(DataInput di, byte[] b) throws IOException - { - di.readFully(b, 0, 2); - return (b[0] & 0xff) | (b[1] & 0xff) << 8; - } - - /** - * Read an int in little endian byte order from the given - * DataInput stream using the given byte buffer. - * - * @param di DataInput stream to read from. - * @param b the byte buffer to read in (must be at least 4 bytes long). - * @return The value read. - * - * @exception IOException if a i/o error occured. - * @exception EOFException if the file ends prematurely - */ - private int readLeInt(DataInput di, byte[] b) throws IOException - { - di.readFully(b, 0, 4); - return ((b[0] & 0xff) | (b[1] & 0xff) << 8) - | ((b[2] & 0xff) | (b[3] & 0xff) << 8) << 16; - } - - /** - * Read an unsigned short in little endian byte order from the given - * byte buffer at the given offset. - * - * @param b the byte array to read from. - * @param off the offset to read from. - * @return The value read. - */ - private int readLeShort(byte[] b, int off) - { - return (b[off] & 0xff) | (b[off+1] & 0xff) << 8; - } - - /** - * Read an int in little endian byte order from the given - * byte buffer at the given offset. - * - * @param b the byte array to read from. - * @param off the offset to read from. - * @return The value read. - */ - private int readLeInt(byte[] b, int off) - { - return ((b[off] & 0xff) | (b[off+1] & 0xff) << 8) - | ((b[off+2] & 0xff) | (b[off+3] & 0xff) << 8) << 16; - } - - - /** * Read the central directory of a zip file and fill the entries * array. This is called exactly once when first needed. It is called * while holding the lock on <code>raf</code>. @@ -246,63 +191,48 @@ public class ZipFile implements ZipConstants { /* Search for the End Of Central Directory. When a zip comment is * present the directory may start earlier. - * FIXME: This searches the whole file in a very slow manner if the - * file isn't a zip file. + * Note that a comment has a maximum length of 64K, so that is the + * maximum we search backwards. */ + PartialInputStream inp = new PartialInputStream(raf, 4096); long pos = raf.length() - ENDHDR; - byte[] ebs = new byte[CENHDR]; - + long top = Math.max(0, pos - 65536); do { - if (pos < 0) + if (pos < top) throw new ZipException ("central directory not found, probably not a zip file: " + name); - raf.seek(pos--); + inp.seek(pos--); } - while (readLeInt(raf, ebs) != ENDSIG); + while (inp.readLeInt() != ENDSIG); - if (raf.skipBytes(ENDTOT - ENDNRD) != ENDTOT - ENDNRD) + if (inp.skip(ENDTOT - ENDNRD) != ENDTOT - ENDNRD) throw new EOFException(name); - int count = readLeShort(raf, ebs); - if (raf.skipBytes(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ) + int count = inp.readLeShort(); + if (inp.skip(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ) throw new EOFException(name); - int centralOffset = readLeInt(raf, ebs); + int centralOffset = inp.readLeInt(); entries = new HashMap(count+count/2); - raf.seek(centralOffset); + inp.seek(centralOffset); - byte[] buffer = new byte[16]; for (int i = 0; i < count; i++) { - raf.readFully(ebs); - if (readLeInt(ebs, 0) != CENSIG) + if (inp.readLeInt() != CENSIG) throw new ZipException("Wrong Central Directory signature: " + name); - int method = readLeShort(ebs, CENHOW); - int dostime = readLeInt(ebs, CENTIM); - int crc = readLeInt(ebs, CENCRC); - int csize = readLeInt(ebs, CENSIZ); - int size = readLeInt(ebs, CENLEN); - int nameLen = readLeShort(ebs, CENNAM); - int extraLen = readLeShort(ebs, CENEXT); - int commentLen = readLeShort(ebs, CENCOM); - - int offset = readLeInt(ebs, CENOFF); - - int needBuffer = Math.max(nameLen, commentLen); - if (buffer.length < needBuffer) - buffer = new byte[needBuffer]; - - raf.readFully(buffer, 0, nameLen); - String name; - try - { - name = new String(buffer, 0, nameLen, "UTF-8"); - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } + inp.skip(6); + int method = inp.readLeShort(); + int dostime = inp.readLeInt(); + int crc = inp.readLeInt(); + int csize = inp.readLeInt(); + int size = inp.readLeInt(); + int nameLen = inp.readLeShort(); + int extraLen = inp.readLeShort(); + int commentLen = inp.readLeShort(); + inp.skip(8); + int offset = inp.readLeInt(); + String name = inp.readString(nameLen); ZipEntry entry = new ZipEntry(name); entry.setMethod(method); @@ -313,20 +243,12 @@ public class ZipFile implements ZipConstants if (extraLen > 0) { byte[] extra = new byte[extraLen]; - raf.readFully(extra); + inp.readFully(extra); entry.setExtra(extra); } if (commentLen > 0) { - raf.readFully(buffer, 0, commentLen); - try - { - entry.setComment(new String(buffer, 0, commentLen, "UTF-8")); - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } + entry.setComment(inp.readString(commentLen)); } entry.offset = offset; entries.put(name, entry); @@ -429,42 +351,6 @@ public class ZipFile implements ZipConstants } } - - //access should be protected by synchronized(raf) - private byte[] locBuf = new byte[LOCHDR]; - - /** - * Checks, if the local header of the entry at index i matches the - * central directory, and returns the offset to the data. - * - * @param entry to check. - * @return the start offset of the (compressed) data. - * - * @exception IOException if a i/o error occured. - * @exception ZipException if the local header doesn't match the - * central directory header - */ - private long checkLocalHeader(ZipEntry entry) throws IOException - { - synchronized (raf) - { - raf.seek(entry.offset); - raf.readFully(locBuf); - - if (readLeInt(locBuf, 0) != LOCSIG) - throw new ZipException("Wrong Local header signature: " + name); - - if (entry.getMethod() != readLeShort(locBuf, LOCHOW)) - throw new ZipException("Compression method mismatch: " + name); - - if (entry.getName().length() != readLeShort(locBuf, LOCNAM)) - throw new ZipException("file name length mismatch: " + name); - - int extraLen = entry.getName().length() + readLeShort(locBuf, LOCEXT); - return entry.offset + LOCHDR + extraLen; - } - } - /** * Creates an input stream reading the given zip entry as * uncompressed data. Normally zip entry should be an entry @@ -497,16 +383,32 @@ public class ZipFile implements ZipConstants if (zipEntry == null) return null; - long start = checkLocalHeader(zipEntry); + PartialInputStream inp = new PartialInputStream(raf, 1024); + inp.seek(zipEntry.offset); + + if (inp.readLeInt() != LOCSIG) + throw new ZipException("Wrong Local header signature: " + name); + + inp.skip(4); + + if (zipEntry.getMethod() != inp.readLeShort()) + throw new ZipException("Compression method mismatch: " + name); + + inp.skip(16); + + int nameLen = inp.readLeShort(); + int extraLen = inp.readLeShort(); + inp.skip(nameLen + extraLen); + + inp.setLength(zipEntry.getCompressedSize()); + int method = zipEntry.getMethod(); - InputStream is = new BufferedInputStream(new PartialInputStream - (raf, start, zipEntry.getCompressedSize())); switch (method) { case ZipOutputStream.STORED: - return is; + return inp; case ZipOutputStream.DEFLATED: - return new InflaterInputStream(is, new Inflater(true)); + return new InflaterInputStream(inp, new Inflater(true)); default: throw new ZipException("Unknown compression method " + method); } @@ -562,21 +464,41 @@ public class ZipFile implements ZipConstants } } - private static class PartialInputStream extends InputStream + private static final class PartialInputStream extends InputStream { private final RandomAccessFile raf; - long filepos, end; + private final byte[] buffer; + private long bufferOffset; + private int pos; + private long end; - public PartialInputStream(RandomAccessFile raf, long start, long len) + public PartialInputStream(RandomAccessFile raf, int bufferSize) + throws IOException { this.raf = raf; - filepos = start; - end = start + len; + buffer = new byte[bufferSize]; + bufferOffset = -buffer.length; + pos = buffer.length; + end = raf.length(); + } + + void setLength(long length) + { + end = bufferOffset + pos + length; + } + + private void fillBuffer() throws IOException + { + synchronized (raf) + { + raf.seek(bufferOffset); + raf.readFully(buffer, 0, (int) Math.min(buffer.length, end - bufferOffset)); + } } public int available() { - long amount = end - filepos; + long amount = end - (bufferOffset + pos); if (amount > Integer.MAX_VALUE) return Integer.MAX_VALUE; return (int) amount; @@ -584,41 +506,130 @@ public class ZipFile implements ZipConstants public int read() throws IOException { - if (filepos == end) + if (bufferOffset + pos >= end) return -1; - synchronized (raf) - { - raf.seek(filepos++); - return raf.read(); - } + if (pos == buffer.length) + { + bufferOffset += buffer.length; + pos = 0; + fillBuffer(); + } + return buffer[pos++] & 0xFF; } public int read(byte[] b, int off, int len) throws IOException { - if (len > end - filepos) + if (len > end - (bufferOffset + pos)) { - len = (int) (end - filepos); + len = (int) (end - (bufferOffset + pos)); if (len == 0) return -1; } - synchronized (raf) - { - raf.seek(filepos); - int count = raf.read(b, off, len); - if (count > 0) - filepos += len; - return count; - } + + int totalBytesRead = Math.min(buffer.length - pos, len); + System.arraycopy(buffer, pos, b, off, totalBytesRead); + pos += totalBytesRead; + off += totalBytesRead; + len -= totalBytesRead; + + while (len > 0) + { + bufferOffset += buffer.length; + pos = 0; + fillBuffer(); + int remain = Math.min(buffer.length, len); + System.arraycopy(buffer, pos, b, off, remain); + pos += remain; + off += remain; + len -= remain; + totalBytesRead += remain; + } + + return totalBytesRead; } - public long skip(long amount) + public long skip(long amount) throws IOException { if (amount < 0) - throw new IllegalArgumentException(); - if (amount > end - filepos) - amount = end - filepos; - filepos += amount; + return 0; + if (amount > end - (bufferOffset + pos)) + amount = end - (bufferOffset + pos); + seek(bufferOffset + pos + amount); return amount; } + + void seek(long newpos) throws IOException + { + long offset = newpos - bufferOffset; + if (offset >= 0 && offset <= buffer.length) + { + pos = (int) offset; + } + else + { + bufferOffset = newpos; + pos = 0; + fillBuffer(); + } + } + + void readFully(byte[] buf) throws IOException + { + if (read(buf, 0, buf.length) != buf.length) + throw new EOFException(); + } + + void readFully(byte[] buf, int off, int len) throws IOException + { + if (read(buf, off, len) != len) + throw new EOFException(); + } + + int readLeShort() throws IOException + { + int b0 = read(); + int b1 = read(); + if (b1 == -1) + throw new EOFException(); + return (b0 & 0xff) | (b1 & 0xff) << 8; + } + + int readLeInt() throws IOException + { + int b0 = read(); + int b1 = read(); + int b2 = read(); + int b3 = read(); + if (b3 == -1) + throw new EOFException(); + return ((b0 & 0xff) | (b1 & 0xff) << 8) + | ((b2 & 0xff) | (b3 & 0xff) << 8) << 16; + } + + String readString(int length) throws IOException + { + if (length > end - (bufferOffset + pos)) + throw new EOFException(); + + try + { + if (buffer.length - pos >= length) + { + String s = new String(buffer, pos, length, "UTF-8"); + pos += length; + return s; + } + else + { + byte[] b = new byte[length]; + readFully(b); + return new String(b, 0, length, "UTF-8"); + } + } + catch (UnsupportedEncodingException uee) + { + throw new AssertionError(uee); + } + } } } diff --git a/libjava/classpath/java/util/zip/ZipOutputStream.java b/libjava/classpath/java/util/zip/ZipOutputStream.java index 5c593b2c45a..d292f7d40e2 100644 --- a/libjava/classpath/java/util/zip/ZipOutputStream.java +++ b/libjava/classpath/java/util/zip/ZipOutputStream.java @@ -1,5 +1,5 @@ /* ZipOutputStream.java -- - Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -161,6 +161,16 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant } /** + * Write a long value as an int. Some of the zip constants + * are declared as longs even though they fit perfectly well + * into integers. + */ + private void writeLeInt(long value) throws IOException + { + writeLeInt((int) value); + } + + /** * Starts a new Zip entry. It automatically closes the previous * entry if present. If the compression method is stored, the entry * must have a valid size and crc, otherwise all elements (except |