summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/awt/AWTEvent.java103
-rw-r--r--java/awt/BasicStroke.java177
-rw-r--r--java/awt/BorderLayout.java123
-rw-r--r--java/awt/CardLayout.java26
-rw-r--r--java/awt/Checkbox.java27
-rw-r--r--java/awt/Choice.java25
-rw-r--r--java/awt/Component.java252
-rw-r--r--java/awt/Container.java412
-rw-r--r--java/awt/Cursor.java4
-rw-r--r--java/awt/EventQueue.java22
-rw-r--r--java/awt/Frame.java698
-rw-r--r--java/awt/Graphics.java3
-rw-r--r--java/awt/LightweightDispatcher.java154
-rw-r--r--java/awt/Menu.java59
-rw-r--r--java/awt/MenuBar.java575
-rw-r--r--java/awt/MenuComponent.java2028
-rw-r--r--java/awt/Scrollbar.java30
-rw-r--r--java/awt/TextField.java1
-rw-r--r--java/awt/Toolkit.java208
-rw-r--r--java/awt/Window.java81
-rw-r--r--java/awt/datatransfer/DataFlavor.java50
-rw-r--r--java/awt/dnd/DragSource.java25
-rw-r--r--java/awt/event/AWTEventListenerProxy.java68
-rw-r--r--java/awt/peer/ComponentPeer.java284
-rw-r--r--java/awt/print/NoPrinterJob.java124
-rw-r--r--java/awt/print/PageFormat.java437
-rw-r--r--java/awt/print/Pageable.java119
-rw-r--r--java/awt/print/Paper.java345
-rw-r--r--java/awt/print/PrinterGraphics.java35
-rw-r--r--java/awt/print/PrinterJob.java4
-rw-r--r--java/beans/DefaultPersistenceDelegate.java17
-rw-r--r--java/beans/Encoder.java45
-rw-r--r--java/beans/EventSetDescriptor.java1109
-rw-r--r--java/beans/PersistenceDelegate.java5
-rw-r--r--java/beans/PropertyChangeSupport.java25
-rw-r--r--java/beans/XMLDecoder.java6
-rw-r--r--java/beans/XMLEncoder.java2
-rw-r--r--java/io/InputStream.java4
-rw-r--r--java/io/InputStreamReader.java20
-rw-r--r--java/io/ObjectInputStream.java19
-rw-r--r--java/io/ObjectOutputStream.java4
-rw-r--r--java/lang/Character.java1343
-rw-r--r--java/lang/ClassNotFoundException.java5
-rw-r--r--java/lang/Math.java351
-rw-r--r--java/lang/String.java70
-rw-r--r--java/lang/System.java17
-rw-r--r--java/lang/Thread.java2
-rw-r--r--java/lang/reflect/Proxy.java44
-rw-r--r--java/math/BigDecimal.java17
-rw-r--r--java/net/InetAddress.java4
-rw-r--r--java/net/ServerSocket.java10
-rw-r--r--java/net/SocketPermission.java384
-rw-r--r--java/net/URI.java13
-rw-r--r--java/net/URLClassLoader.java48
-rw-r--r--java/net/URLConnection.java5
-rw-r--r--java/rmi/AccessException.java5
-rw-r--r--java/rmi/AlreadyBoundException.java7
-rw-r--r--java/rmi/MarshalledObject.java103
-rw-r--r--java/rmi/Naming.java226
-rw-r--r--java/rmi/NoSuchObjectException.java9
-rw-r--r--java/rmi/NotBoundException.java11
-rw-r--r--java/rmi/RMISecurityException.java14
-rw-r--r--java/rmi/Remote.java19
-rw-r--r--java/rmi/RemoteException.java5
-rw-r--r--java/rmi/StubNotFoundException.java7
-rw-r--r--java/rmi/package.html2
-rw-r--r--java/rmi/registry/Registry.java24
-rw-r--r--java/rmi/server/RemoteObjectInvocationHandler.java221
-rw-r--r--java/rmi/server/RemoteRef.java64
-rw-r--r--java/rmi/server/RemoteStub.java23
-rw-r--r--java/rmi/server/UnicastRemoteObject.java213
-rw-r--r--java/security/AlgorithmParameterGenerator.java197
-rw-r--r--java/security/AlgorithmParameters.java250
-rw-r--r--java/security/Identity.java263
-rw-r--r--java/security/IdentityScope.java168
-rw-r--r--java/security/KeyFactory.java204
-rw-r--r--java/security/KeyPairGenerator.java294
-rw-r--r--java/security/MessageDigest.java257
-rw-r--r--java/security/Policy.java175
-rw-r--r--java/security/ProtectionDomain.java137
-rw-r--r--java/security/Security.java396
-rw-r--r--java/security/Signature.java527
-rw-r--r--java/security/SignatureSpi.java290
-rw-r--r--java/security/SignedObject.java177
-rw-r--r--java/security/Signer.java92
-rw-r--r--java/security/interfaces/RSAMultiPrimePrivateCrtKey.java27
-rw-r--r--java/security/spec/PSSParameterSpec.java25
-rw-r--r--java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java78
-rw-r--r--java/security/spec/RSAOtherPrimeInfo.java35
-rw-r--r--java/util/AbstractCollection.java16
-rw-r--r--java/util/Hashtable.java386
-rw-r--r--java/util/logging/LogManager.java53
-rw-r--r--java/util/logging/SimpleFormatter.java10
-rw-r--r--java/util/regex/MatchResult.java81
-rw-r--r--java/util/regex/Matcher.java25
-rw-r--r--java/util/regex/PatternSyntaxException.java1
-rw-r--r--java/util/zip/ZipConstants.java10
-rw-r--r--java/util/zip/ZipFile.java397
-rw-r--r--java/util/zip/ZipOutputStream.java12
99 files changed, 9435 insertions, 6169 deletions
diff --git a/java/awt/AWTEvent.java b/java/awt/AWTEvent.java
index ad9533f9c..d10433cb3 100644
--- a/java/awt/AWTEvent.java
+++ b/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/java/awt/BasicStroke.java b/java/awt/BasicStroke.java
index bb008e4c7..4eece75c9 100644
--- a/java/awt/BasicStroke.java
+++ b/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/java/awt/BorderLayout.java b/java/awt/BorderLayout.java
index 7c8c582a9..50061ec67 100644
--- a/java/awt/BorderLayout.java
+++ b/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/java/awt/CardLayout.java b/java/awt/CardLayout.java
index 8582c5f09..8b3fea2ca 100644
--- a/java/awt/CardLayout.java
+++ b/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/java/awt/Checkbox.java b/java/awt/Checkbox.java
index 93f609247..eea443edf 100644
--- a/java/awt/Checkbox.java
+++ b/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/java/awt/Choice.java b/java/awt/Choice.java
index 9b9fe4b97..9fbcd9343 100644
--- a/java/awt/Choice.java
+++ b/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/java/awt/Component.java b/java/awt/Component.java
index 7d4346582..eb0352147 100644
--- a/java/awt/Component.java
+++ b/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);
@@ -3431,6 +3438,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. */
@@ -4482,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
@@ -4598,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)
@@ -4771,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 ());
@@ -4791,16 +4922,12 @@ p * <li>the set of backward traversal keys
void dispatchEventImpl(AWTEvent e)
{
- Event oldEvent = translateEvent (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
@@ -4926,16 +5053,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;
}
@@ -5015,9 +5132,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/java/awt/Container.java b/java/awt/Container.java
index 6d4a34571..dfea3ac12 100644
--- a/java/awt/Container.java
+++ b/java/awt/Container.java
@@ -1,5 +1,5 @@
/* Container.java -- parent container class in AWT
- Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005
+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006
Free Software Foundation
This file is part of GNU Classpath.
@@ -43,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;
@@ -63,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
@@ -90,11 +86,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;
@@ -103,7 +102,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. */
@@ -189,25 +187,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.
*
@@ -387,6 +366,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;
@@ -395,7 +376,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.
@@ -779,16 +760,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;
}
/**
@@ -819,8 +801,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);
}
@@ -1561,28 +1546,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");
- changeSupport.addPropertyChangeListener (name, listener);
+ // 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;
+ }
+ }
+
+ /**
+ * 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.
@@ -1604,17 +1666,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);
- }
+ }
}
}
@@ -1635,10 +1697,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
@@ -1653,10 +1714,6 @@ 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
@@ -1747,15 +1804,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);
@@ -2002,229 +2050,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/java/awt/Cursor.java b/java/awt/Cursor.java
index 48a63f06f..0ff987cd9 100644
--- a/java/awt/Cursor.java
+++ b/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/java/awt/EventQueue.java b/java/awt/EventQueue.java
index 235ad2ac1..72dcf7046 100644
--- a/java/awt/EventQueue.java
+++ b/java/awt/EventQueue.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package java.awt;
+import java.awt.event.AWTEventListenerProxy;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.InputMethodEvent;
@@ -459,6 +460,8 @@ public class EventQueue
else if (evt instanceof InvocationEvent)
lastWhen = ((InvocationEvent) evt).getWhen();
+ globalDispatchEvent(evt);
+
if (evt instanceof ActiveEvent)
{
ActiveEvent active_evt = (ActiveEvent) evt;
@@ -482,6 +485,25 @@ public class EventQueue
}
/**
+ * Dispatches events to listeners registered to the current Toolkit.
+ *
+ * @param ev the event to dispatch
+ */
+ private void globalDispatchEvent(AWTEvent ev)
+ {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ // 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.
+ AWTEventListenerProxy[] l = toolkit.awtEventListeners;
+ for (int i = 0; i < l.length; ++i)
+ {
+ AWTEventListenerProxy proxy = l[i];
+ if ((proxy.getEventMask() & AWTEvent.eventIdToMask(ev.getID())) != 0)
+ proxy.eventDispatched(ev);
+ }
+ }
+
+ /**
* Returns the timestamp of the most recent event that had a timestamp, or
* the initialization time of the event queue if no events have been fired.
* At present, only <code>InputEvent</code>s, <code>ActionEvent</code>s,
diff --git a/java/awt/Frame.java b/java/awt/Frame.java
index d6651f83e..7003dac91 100644
--- a/java/awt/Frame.java
+++ b/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/java/awt/Graphics.java b/java/awt/Graphics.java
index a28ca7e42..09bf7cacf 100644
--- a/java/awt/Graphics.java
+++ b/java/awt/Graphics.java
@@ -617,6 +617,9 @@ public abstract class Graphics
*/
public boolean hitClip(int x, int y, int width, int height)
{
+ Shape clip = getClip();
+ if (clip == null)
+ return true;
return getClip().intersects(x, y, width, height);
}
diff --git a/java/awt/LightweightDispatcher.java b/java/awt/LightweightDispatcher.java
new file mode 100644
index 000000000..1eccb5d5d
--- /dev/null
+++ b/java/awt/LightweightDispatcher.java
@@ -0,0 +1,154 @@
+/* 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.AWTEventListener;
+import java.awt.event.MouseEvent;
+
+/**
+ * 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
+ implements AWTEventListener
+{
+
+ /**
+ * 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;
+
+ /**
+ * Receives notification if a mouse event passes along the eventqueue.
+ *
+ * @param event the event
+ */
+ public void eventDispatched(AWTEvent event)
+ {
+ if (event instanceof MouseEvent && event.getSource() instanceof Window)
+ {
+ MouseEvent mouseEvent = (MouseEvent) event;
+ handleMouseEvent(mouseEvent);
+ }
+ }
+
+ /**
+ * 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);
+ }
+ lastTarget = target;
+
+
+ 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_DRAGGED:
+ target = dragTarget;
+ break;
+ default:
+ // Do nothing in other cases.
+ break;
+ }
+
+ 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/java/awt/Menu.java b/java/awt/Menu.java
index 13ebb5211..6daec72cf 100644
--- a/java/awt/Menu.java
+++ b/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/java/awt/MenuBar.java b/java/awt/MenuBar.java
index 97156aefe..3c6b91564 100644
--- a/java/awt/MenuBar.java
+++ b/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<MenuShortcut>
-shortcuts()
-{
- Vector<MenuShortcut> shortcuts = new Vector<MenuShortcut>();
- 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/java/awt/MenuComponent.java b/java/awt/MenuComponent.java
index 375d08436..9bb875069 100644
--- a/java/awt/MenuComponent.java
+++ b/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/java/awt/Scrollbar.java b/java/awt/Scrollbar.java
index ef173f111..ef8d6d59e 100644
--- a/java/awt/Scrollbar.java
+++ b/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/java/awt/TextField.java b/java/awt/TextField.java
index 0125b25f8..ff32afa88 100644
--- a/java/awt/TextField.java
+++ b/java/awt/TextField.java
@@ -397,6 +397,7 @@ addNotify()
return;
setPeer((ComponentPeer)getToolkit().createTextField(this));
+ super.addNotify();
}
/*************************************************************************/
diff --git a/java/awt/Toolkit.java b/java/awt/Toolkit.java
index 14282f666..ed2433be0 100644
--- a/java/awt/Toolkit.java
+++ b/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.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
@@ -77,6 +80,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.Hashtable;
import java.util.Map;
import java.util.Properties;
@@ -117,10 +121,21 @@ 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[1];
+ awtEventListeners[0] =
+ new AWTEventListenerProxy(AWTEvent.MOUSE_EVENT_MASK
+ | AWTEvent.MOUSE_MOTION_EVENT_MASK,
+ new LightweightDispatcher());
}
/**
@@ -352,7 +367,7 @@ public abstract class Toolkit
*/
protected LightweightPeer createComponent(Component target)
{
- return new gnu.java.awt.peer.GLightweightPeer (target);
+ return new GLightweightPeer(target);
}
/**
@@ -968,33 +983,210 @@ 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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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(&quot;listenToAllAWTEvents&quot;)</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()]);
}
/**
diff --git a/java/awt/Window.java b/java/awt/Window.java
index 61b380edf..66d9324af 100644
--- a/java/awt/Window.java
+++ b/java/awt/Window.java
@@ -282,51 +282,54 @@ public class Window extends Container implements Accessible
@Deprecated
public void show()
{
- if (parent != null && !parent.isDisplayable())
- parent.addNotify();
- if (peer == null)
- addNotify();
-
- // Show visible owned windows.
synchronized (getTreeLock())
- {
- 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;
+ }
}
- }
}
/**
diff --git a/java/awt/datatransfer/DataFlavor.java b/java/awt/datatransfer/DataFlavor.java
index 606cfe035..f7c103c72 100644
--- a/java/awt/datatransfer/DataFlavor.java
+++ b/java/awt/datatransfer/DataFlavor.java
@@ -161,38 +161,42 @@ private String humanPresentableName;
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,
@@ -207,7 +211,13 @@ private String humanPresentableName;
}
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/java/awt/dnd/DragSource.java b/java/awt/dnd/DragSource.java
index 09c9fc48e..014998913 100644
--- a/java/awt/dnd/DragSource.java
+++ b/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 <T extends DragGestureRecognizer> T
createDragGestureRecognizer(Class<T> 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 (T) dgr;
}
public DragGestureRecognizer
diff --git a/java/awt/event/AWTEventListenerProxy.java b/java/awt/event/AWTEventListenerProxy.java
index 3d9958b1a..55a4bfe37 100644
--- a/java/awt/event/AWTEventListenerProxy.java
+++ b/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/java/awt/peer/ComponentPeer.java b/java/awt/peer/ComponentPeer.java
index 1ba169232..97b96f49c 100644
--- a/java/awt/peer/ComponentPeer.java
+++ b/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/java/awt/print/NoPrinterJob.java b/java/awt/print/NoPrinterJob.java
new file mode 100644
index 000000000..e9659a147
--- /dev/null
+++ b/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/java/awt/print/PageFormat.java b/java/awt/print/PageFormat.java
index 6399552de..0a8aa3ed0 100644
--- a/java/awt/print/PageFormat.java
+++ b/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/java/awt/print/Pageable.java b/java/awt/print/Pageable.java
index 12fa542a8..d61195a92 100644
--- a/java/awt/print/Pageable.java
+++ b/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/java/awt/print/Paper.java b/java/awt/print/Paper.java
index 4579da3ea..fb7ba9115 100644
--- a/java/awt/print/Paper.java
+++ b/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/java/awt/print/PrinterGraphics.java b/java/awt/print/PrinterGraphics.java
index 5ca641904..62fde8406 100644
--- a/java/awt/print/PrinterGraphics.java
+++ b/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/java/awt/print/PrinterJob.java b/java/awt/print/PrinterJob.java
index e1aeabc3e..7f67a6b04 100644
--- a/java/awt/print/PrinterJob.java
+++ b/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/java/beans/DefaultPersistenceDelegate.java b/java/beans/DefaultPersistenceDelegate.java
index 9dd1ae564..ca1041fef 100644
--- a/java/beans/DefaultPersistenceDelegate.java
+++ b/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/java/beans/Encoder.java b/java/beans/Encoder.java
index e7b53d786..cde1735f4 100644
--- a/java/beans/Encoder.java
+++ b/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/java/beans/EventSetDescriptor.java b/java/beans/EventSetDescriptor.java
index e687b8a30..381a45303 100644
--- a/java/beans/EventSetDescriptor.java
+++ b/java/beans/EventSetDescriptor.java
@@ -45,398 +45,719 @@ import java.lang.reflect.Modifier;
import java.util.Vector;
/**
- ** EventSetDescriptor describes the hookup between an event source
- ** class and an event listener class.
- **
- ** EventSets have several attributes: the listener class, the events
- ** that can be fired to the listener (methods in the listener class), and
- ** an add and remove listener method from the event firer's class.<P>
- **
- ** The methods have these constraints on them:<P>
- ** <UL>
- ** <LI>event firing methods: must have <CODE>void</CODE> return value. Any
- ** parameters and exceptions are allowed. May be public, protected or
- ** package-protected. (Don't ask me why that is, I'm just following the spec.
- ** The only place it is even mentioned is in the Java Beans white paper, and
- ** there it is only implied.)</LI>
- ** <LI>add listener method: must have <CODE>void</CODE> return value. Must
- ** take exactly one argument, of the listener class's type. May fire either
- ** zero exceptions, or one exception of type <CODE>java.util.TooManyListenersException</CODE>.
- ** Must be public.</LI>
- ** <LI>remove listener method: must have <CODE>void</CODE> return value.
- ** Must take exactly one argument, of the listener class's type. May not
- ** fire any exceptions. Must be public.</LI>
- ** </UL>
- **
- ** A final constraint is that event listener classes must extend from EventListener.<P>
- **
- ** There are also various design patterns associated with some of the methods
- ** of construction. Those are explained in more detail in the appropriate
- ** constructors.<P>
- **
- ** <STRONG>Documentation Convention:</STRONG> for proper
- ** Internalization of Beans inside an RAD tool, sometimes there
- ** are two names for a property or method: a programmatic, or
- ** locale-independent name, which can be used anywhere, and a
- ** localized, display name, for ease of use. In the
- ** documentation I will specify different String values as
- ** either <EM>programmatic</EM> or <EM>localized</EM> to
- ** make this distinction clear.
- **
- ** @author John Keiser
- ** @since JDK1.1
- ** @version 1.1.0, 31 May 1998
- **/
-
-public class EventSetDescriptor extends FeatureDescriptor {
- private Method addListenerMethod;
- private Method removeListenerMethod;
- private Class<?> listenerType;
- private MethodDescriptor[] listenerMethodDescriptors;
- private Method[] listenerMethods;
-
- private boolean unicast;
- private boolean inDefaultEventSet = true;
-
- /** Create a new EventSetDescriptor.
- ** This version of the constructor enforces the rules imposed on the methods
- ** described at the top of this class, as well as searching for:<P>
- ** <OL>
- ** <LI>The event-firing method must be non-private with signature
- ** <CODE>void &lt;listenerMethodName&gt;(&lt;eventSetName&gt;Event)</CODE>
- ** (where <CODE>&lt;eventSetName&gt;</CODE> has its first character capitalized
- ** by the constructor and the Event is a descendant of
- ** <CODE>java.util.EventObject</CODE>) in class <CODE>listenerType</CODE>
- ** (any exceptions may be thrown).
- ** <B>Implementation note:</B> Note that there could conceivably be multiple
- ** methods with this type of signature (example: java.util.MouseEvent vs.
- ** my.very.own.MouseEvent). In this implementation, all methods fitting the
- ** description will be put into the <CODE>EventSetDescriptor</CODE>, even
- ** though the spec says only one should be chosen (they probably weren't thinking as
- ** pathologically as I was). I don't like arbitrarily choosing things.
- ** If your class has only one such signature, as most do, you'll have no problems.</LI>
- ** <LI>The add and remove methods must be public and named
- ** <CODE>void add&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</CODE> and
- ** <CODE>void remove&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</CODE> in
- ** in class <CODE>eventSourceClass</CODE>, where
- ** <CODE>&lt;eventSetName&gt;</CODE> will have its first letter capitalized.
- ** Standard exception rules (see class description) apply.</LI>
- ** </OL>
- ** @param eventSourceClass the class containing the add/remove listener methods.
- ** @param eventSetName the programmatic name of the event set, generally starting
- ** with a lowercase letter (i.e. fooManChu instead of FooManChu). This will be used
- ** to generate the name of the event object as well as the names of the add and
- ** remove methods.
- ** @param listenerType the class containing the event firing method.
- ** @param listenerMethodName the name of the event firing method.
- ** @exception IntrospectionException if listenerType is not an EventListener,
- ** or if methods are not found or are invalid.
- **/
- public EventSetDescriptor(Class<?> eventSourceClass,
- String eventSetName,
- Class<?> listenerType,
- String listenerMethodName) throws IntrospectionException {
- setName(eventSetName);
- if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
- throw new IntrospectionException("Listener type is not an EventListener.");
- }
-
- String[] names = new String[1];
- names[0] = listenerMethodName;
-
- try {
- eventSetName = Character.toUpperCase(eventSetName.charAt(0)) + eventSetName.substring(1);
- } catch(StringIndexOutOfBoundsException e) {
- eventSetName = "";
- }
-
- findMethods(eventSourceClass,listenerType,names,"add"+eventSetName+"Listener","remove"+eventSetName+"Listener",eventSetName+"Event");
- this.listenerType = listenerType;
- checkAddListenerUnicast();
- if(this.removeListenerMethod.getExceptionTypes().length > 0) {
- throw new IntrospectionException("Listener remove method throws exceptions.");
- }
- }
-
- /** Create a new EventSetDescriptor.
- ** This form of the constructor allows you to specify the names of the methods and adds
- ** no new constraints on top of the rules already described at the top of the class.<P>
- **
- ** @param eventSourceClass the class containing the add and remove listener methods.
- ** @param eventSetName the programmatic name of the event set, generally starting
- ** with a lowercase letter (i.e. fooManChu instead of FooManChu).
- ** @param listenerType the class containing the event firing methods.
- ** @param listenerMethodNames the names of the even firing methods.
- ** @param addListenerMethodName the name of the add listener method.
- ** @param removeListenerMethodName the name of the remove listener method.
- ** @exception IntrospectionException if listenerType is not an EventListener
- ** or if methods are not found or are invalid.
- **/
- public EventSetDescriptor(Class<?> eventSourceClass,
- String eventSetName,
- Class<?> listenerType,
- String[] listenerMethodNames,
- String addListenerMethodName,
- String removeListenerMethodName) throws IntrospectionException {
- setName(eventSetName);
- if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
- throw new IntrospectionException("Listener type is not an EventListener.");
- }
-
- findMethods(eventSourceClass,listenerType,listenerMethodNames,addListenerMethodName,removeListenerMethodName,null);
- this.listenerType = listenerType;
- checkAddListenerUnicast();
- if(this.removeListenerMethod.getExceptionTypes().length > 0) {
- throw new IntrospectionException("Listener remove method throws exceptions.");
- }
- }
-
- /** Create a new EventSetDescriptor.
- ** This form of constructor allows you to explicitly say which methods do what, and
- ** no reflection is done by the EventSetDescriptor. The methods are, however,
- ** checked to ensure that they follow the rules set forth at the top of the class.
- ** @param eventSetName the programmatic name of the event set, generally starting
- ** with a lowercase letter (i.e. fooManChu instead of FooManChu).
- ** @param listenerType the class containing the listenerMethods.
- ** @param listenerMethods the event firing methods.
- ** @param addListenerMethod the add listener method.
- ** @param removeListenerMethod the remove listener method.
- ** @exception IntrospectionException if the listenerType is not an EventListener,
- ** or any of the methods are invalid.
- **/
- public EventSetDescriptor(String eventSetName,
- Class<?> listenerType,
- Method[] listenerMethods,
- Method addListenerMethod,
- Method removeListenerMethod) throws IntrospectionException {
- setName(eventSetName);
- if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
- throw new IntrospectionException("Listener type is not an EventListener.");
- }
-
- this.listenerMethods = listenerMethods;
- this.addListenerMethod = addListenerMethod;
- this.removeListenerMethod = removeListenerMethod;
- this.listenerType = listenerType;
- checkMethods();
- checkAddListenerUnicast();
- if(this.removeListenerMethod.getExceptionTypes().length > 0) {
- throw new IntrospectionException("Listener remove method throws exceptions.");
- }
- }
-
- /** Create a new EventSetDescriptor.
- ** This form of constructor allows you to explicitly say which methods do what, and
- ** no reflection is done by the EventSetDescriptor. The methods are, however,
- ** checked to ensure that they follow the rules set forth at the top of the class.
- ** @param eventSetName the programmatic name of the event set, generally starting
- ** with a lowercase letter (i.e. fooManChu instead of FooManChu).
- ** @param listenerType the class containing the listenerMethods.
- ** @param listenerMethodDescriptors the event firing methods.
- ** @param addListenerMethod the add listener method.
- ** @param removeListenerMethod the remove listener method.
- ** @exception IntrospectionException if the listenerType is not an EventListener,
- ** or any of the methods are invalid.
- **/
- public EventSetDescriptor(String eventSetName,
- Class<?> listenerType,
- MethodDescriptor[] listenerMethodDescriptors,
- Method addListenerMethod,
- Method removeListenerMethod) throws IntrospectionException {
- setName(eventSetName);
- if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
- throw new IntrospectionException("Listener type is not an EventListener.");
- }
-
- this.listenerMethodDescriptors = listenerMethodDescriptors;
- this.listenerMethods = new Method[listenerMethodDescriptors.length];
- for(int i=0;i<this.listenerMethodDescriptors.length;i++) {
- this.listenerMethods[i] = this.listenerMethodDescriptors[i].getMethod();
- }
-
- this.addListenerMethod = addListenerMethod;
- this.removeListenerMethod = removeListenerMethod;
- this.listenerType = listenerType;
- checkMethods();
- checkAddListenerUnicast();
- if(this.removeListenerMethod.getExceptionTypes().length > 0) {
- throw new IntrospectionException("Listener remove method throws exceptions.");
- }
- }
-
- /** Get the class that contains the event firing methods. **/
- public Class<?> getListenerType() {
- return listenerType;
- }
-
- /** Get the event firing methods. **/
- public Method[] getListenerMethods() {
- return listenerMethods;
- }
-
- /** Get the event firing methods as MethodDescriptors. **/
- public MethodDescriptor[] getListenerMethodDescriptors() {
- if(listenerMethodDescriptors == null) {
- listenerMethodDescriptors = new MethodDescriptor[listenerMethods.length];
- for(int i=0;i<listenerMethods.length;i++) {
- listenerMethodDescriptors[i] = new MethodDescriptor(listenerMethods[i]);
- }
- }
- return listenerMethodDescriptors;
- }
-
- /** Get the add listener method. **/
- public Method getAddListenerMethod() {
- return addListenerMethod;
- }
-
- /** Get the remove listener method. **/
- public Method getRemoveListenerMethod() {
- return removeListenerMethod;
- }
-
- /** Set whether or not multiple listeners may be added.
- ** @param unicast whether or not multiple listeners may be added.
- **/
- public void setUnicast(boolean unicast) {
- this.unicast = unicast;
- }
-
- /** Get whether or not multiple listeners may be added. (Defaults to false.) **/
- public boolean isUnicast() {
- return unicast;
- }
-
- /** Set whether or not this is in the default event set.
- ** @param inDefaultEventSet whether this is in the default event set.
- **/
- public void setInDefaultEventSet(boolean inDefaultEventSet) {
- this.inDefaultEventSet = inDefaultEventSet;
- }
-
- /** Get whether or not this is in the default event set. (Defaults to true.)**/
- public boolean isInDefaultEventSet() {
- return inDefaultEventSet;
- }
-
- private void checkAddListenerUnicast() throws IntrospectionException {
- Class[] addListenerExceptions = this.addListenerMethod.getExceptionTypes();
- if(addListenerExceptions.length > 1) {
- throw new IntrospectionException("Listener add method throws too many exceptions.");
- } else if(addListenerExceptions.length == 1
- && !java.util.TooManyListenersException.class.isAssignableFrom(addListenerExceptions[0])) {
- throw new IntrospectionException("Listener add method throws too many exceptions.");
- }
- }
-
- private void checkMethods() throws IntrospectionException {
- if(!addListenerMethod.getDeclaringClass().isAssignableFrom(removeListenerMethod.getDeclaringClass())
- && !removeListenerMethod.getDeclaringClass().isAssignableFrom(addListenerMethod.getDeclaringClass())) {
- throw new IntrospectionException("add and remove listener methods do not come from the same class. This is bad.");
- }
- if(!addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
- || addListenerMethod.getParameterTypes().length != 1
- || !listenerType.equals(addListenerMethod.getParameterTypes()[0])
- || !Modifier.isPublic(addListenerMethod.getModifiers())) {
- throw new IntrospectionException("Add Listener Method invalid.");
- }
- if(!removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
- || removeListenerMethod.getParameterTypes().length != 1
- || !listenerType.equals(removeListenerMethod.getParameterTypes()[0])
- || removeListenerMethod.getExceptionTypes().length > 0
- || !Modifier.isPublic(removeListenerMethod.getModifiers())) {
- throw new IntrospectionException("Remove Listener Method invalid.");
- }
-
- for(int i=0;i<listenerMethods.length;i++) {
- if(!listenerMethods[i].getReturnType().equals(java.lang.Void.TYPE)
- || Modifier.isPrivate(listenerMethods[i].getModifiers())) {
- throw new IntrospectionException("Event Method " + listenerMethods[i].getName() + " non-void or private.");
- }
- if(!listenerMethods[i].getDeclaringClass().isAssignableFrom(listenerType)) {
- throw new IntrospectionException("Event Method " + listenerMethods[i].getName() + " not from class " + listenerType.getName());
- }
- }
- }
-
- private void findMethods(Class eventSourceClass,
- Class listenerType,
- String listenerMethodNames[],
- String addListenerMethodName,
- String removeListenerMethodName,
- String absurdEventClassCheckName) throws IntrospectionException {
-
- /* Find add listener method and remove listener method. */
- Class[] listenerArgList = new Class[1];
- listenerArgList[0] = listenerType;
- try {
- this.addListenerMethod = eventSourceClass.getMethod(addListenerMethodName,listenerArgList);
- } catch(SecurityException E) {
- throw new IntrospectionException("SecurityException trying to access method " + addListenerMethodName + ".");
- } catch(NoSuchMethodException E) {
- throw new IntrospectionException("Could not find method " + addListenerMethodName + ".");
- }
-
- if(this.addListenerMethod == null || !this.addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) {
- throw new IntrospectionException("Add listener method does not exist, is not public, or is not void.");
- }
-
- try {
- this.removeListenerMethod = eventSourceClass.getMethod(removeListenerMethodName,listenerArgList);
- } catch(SecurityException E) {
- throw new IntrospectionException("SecurityException trying to access method " + removeListenerMethodName + ".");
- } catch(NoSuchMethodException E) {
- throw new IntrospectionException("Could not find method " + removeListenerMethodName + ".");
- }
- if(this.removeListenerMethod == null || !this.removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) {
- throw new IntrospectionException("Remove listener method does not exist, is not public, or is not void.");
- }
-
- /* Find the listener methods. */
- Method[] methods;
- try {
- methods = ClassHelper.getAllMethods(listenerType);
- } catch(SecurityException E) {
- throw new IntrospectionException("Security: You cannot access fields in this class.");
- }
-
- Vector chosenMethods = new Vector();
- boolean[] listenerMethodFound = new boolean[listenerMethodNames.length];
- for(int i=0;i<methods.length;i++) {
- if(Modifier.isPrivate(methods[i].getModifiers())) {
- continue;
- }
- Method currentMethod = methods[i];
- Class retval = currentMethod.getReturnType();
- if(retval.equals(java.lang.Void.TYPE)) {
- for(int j=0;j<listenerMethodNames.length;j++) {
- if(currentMethod.getName().equals(listenerMethodNames[j])
- && (absurdEventClassCheckName == null
- || (currentMethod.getParameterTypes().length == 1
- && ((currentMethod.getParameterTypes()[0]).getName().equals(absurdEventClassCheckName)
- || (currentMethod.getParameterTypes()[0]).getName().endsWith("."+absurdEventClassCheckName)
- )
- )
- )
- ) {
- chosenMethods.addElement(currentMethod);
- listenerMethodFound[j] = true;
- }
- }
- }
- }
-
- /* Make sure we found all the methods we were looking for. */
- for(int i=0;i<listenerMethodFound.length;i++) {
- if(!listenerMethodFound[i]) {
- throw new IntrospectionException("Could not find event method " + listenerMethodNames[i]);
- }
- }
-
- /* Now that we've chosen the listener methods we want, store them. */
- this.listenerMethods = new Method[chosenMethods.size()];
- for(int i=0;i<chosenMethods.size();i++) {
- this.listenerMethods[i] = (Method)chosenMethods.elementAt(i);
- }
- }
+ * EventSetDescriptor describes the hookup between an event source class and
+ * an event listener class.
+ *
+ * <p>EventSets have several attributes: the listener class,
+ * the events that can be fired to the listener (methods in the listener
+ * class), and an add and remove listener method from the event firer's
+ * class.
+ * </p>
+ *
+ * <p>
+ * The methods have these constraints on them:
+ * <ul>
+ * <li>event firing methods: must have <code>void</code> return value. Any
+ * parameters and exceptions are allowed. May be public, protected or
+ * package-protected. (Don't ask me why that is, I'm just following the spec.
+ * The only place it is even mentioned is in the Java Beans white paper, and
+ * there it is only implied.)</li>
+ *
+ * <li>add listener method: must have <code>void</code> return value. Must
+ * take exactly one argument, of the listener class's type. May fire either
+ * zero exceptions, or one exception of type
+ * <code>java.util.TooManyListenersException</code>.
+ * Must be public.</li>
+ *
+ * <li>remove listener method: must have <code>void</code> return value. Must
+ * take exactly one argument, of the listener class's type. May not fire any
+ * exceptions. Must be public.</li>
+ * </ul>
+ *
+ * <p>
+ * A final constraint is that event listener classes must extend from
+ * EventListener.
+ * </p>
+ *
+ * <p>
+ * There are also various design patterns associated with some of the methods
+ * of construction. Those are explained in more detail in the appropriate
+ * constructors.
+ * </p>
+ *
+ * <p>
+ * <strong>Documentation Convention:</strong> for proper Internalization of
+ * Beans inside an RAD tool, sometimes there are two names for a property or
+ * method: a programmatic, or locale-independent name, which can be used
+ * anywhere, and a localized, display name, for ease of use. In the
+ * documentation I will specify different String values as either
+ * <em>programmatic</em> or <em>localized</em> to make this distinction clear.
+ *
+ * @author John Keiser
+ * @author Robert Schuster (robertschuster@fsfe.org)
+ * @since 1.1
+ */
+
+public class EventSetDescriptor extends FeatureDescriptor
+{
+ private Method addListenerMethod;
+
+ private Method removeListenerMethod;
+
+ private Class listenerType;
+
+ private MethodDescriptor[] listenerMethodDescriptors;
+
+ private Method[] listenerMethods;
+
+ private Method getListenerMethod;
+
+ private boolean unicast;
+
+ private boolean inDefaultEventSet = true;
+
+ /**
+ * Creates a new <code>EventSetDescriptor</code<.
+ *
+ * <p>
+ * This version of the constructor enforces the rules imposed on the methods
+ * described at the top of this class, as well as searching for:
+ * </p>
+ *
+ * <ol>
+ * <li>
+ * The event-firing method must be non-private with signature <code>void
+ * &lt;listenerMethodName&gt;(&lt;eventSetName&gt;Event)</code> (where
+ * <code>&lt;eventSetName&gt;</code> has its first character capitalized
+ * by the constructor and the Event is a descendant of
+ * {@link java.util.EventObject}) in class <code>listenerType</code>
+ * (any exceptions may be thrown). <b>Implementation note:</b> Note that
+ * there could conceivably be multiple methods with this type of signature
+ * (example: <code>java.util.MouseEvent</code> vs.
+ * <code>my.very.own.MouseEvent</code>). In this implementation, all
+ * methods fitting the description will be put into the
+ * <code>EventSetDescriptor</code>, even though the spec says only one
+ * should be chosen (they probably weren't thinking as pathologically as I
+ * was). I don't like arbitrarily choosing things. If your class has only one
+ * such signature, as most do, you'll have no problems.</li>
+ *
+ * <li>The add and remove methods must be public and named <code>void
+ * add&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</code> and
+ * <code>void remove&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</code>
+ * in in class <code>eventSourceClass</code>, where
+ * <code>&lt;eventSetName&gt;</code> will have its first letter capitalized.
+ * Standard exception rules (see class description) apply.</li>
+ * </ol>
+ *
+ * @param eventSourceClass
+ * the class containing the add/remove listener methods.
+ * @param eventSetName
+ * the programmatic name of the event set, generally starting with a
+ * lowercase letter (i.e. fooManChu instead of FooManChu). This will
+ * be used to generate the name of the event object as well as the
+ * names of the add and remove methods.
+ * @param listenerType
+ * the class containing the event firing method.
+ * @param listenerMethodName
+ * the name of the event firing method.
+ * @exception IntrospectionException
+ * if listenerType is not an EventListener, or if methods are not
+ * found or are invalid.
+ */
+ public EventSetDescriptor(Class eventSourceClass, String eventSetName,
+ Class listenerType, String listenerMethodName)
+ throws IntrospectionException
+ {
+ setName(eventSetName);
+ if (!java.util.EventListener.class.isAssignableFrom(listenerType))
+ {
+ throw new IntrospectionException(
+ "Listener type is not an EventListener.");
+ }
+
+ String[] names = new String[1];
+ names[0] = listenerMethodName;
+
+ try
+ {
+ eventSetName = Character.toUpperCase(eventSetName.charAt(0))
+ + eventSetName.substring(1);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ eventSetName = "";
+ }
+
+ findMethods(eventSourceClass, listenerType, names,
+ "add" + eventSetName + "Listener",
+ "remove" + eventSetName + "Listener", eventSetName + "Event");
+ this.listenerType = listenerType;
+ checkAddListenerUnicast();
+ if (this.removeListenerMethod.getExceptionTypes().length > 0)
+ {
+ throw new IntrospectionException(
+ "Listener remove method throws exceptions.");
+ }
+ }
+
+ /**
+ * Creates a new <code>EventSetDescriptor</code>.
+ *
+ * <p>This form of the constructor allows you to specify the names of the
+ * methods and adds no new constraints on top of the rules already described
+ * at the top of the class.
+ * </p>
+ *
+ * @param eventSourceClass
+ * the class containing the add and remove listener methods.
+ * @param eventSetName
+ * the programmatic name of the event set, generally starting with a
+ * lowercase letter (i.e. fooManChu instead of FooManChu).
+ * @param listenerType
+ * the class containing the event firing methods.
+ * @param listenerMethodNames
+ * the names of the even firing methods.
+ * @param addListenerMethodName
+ * the name of the add listener method.
+ * @param removeListenerMethodName
+ * the name of the remove listener method.
+ * @exception IntrospectionException
+ * if listenerType is not an EventListener or if methods are not
+ * found or are invalid.
+ */
+ public EventSetDescriptor(Class eventSourceClass, String eventSetName,
+ Class listenerType, String[] listenerMethodNames,
+ String addListenerMethodName,
+ String removeListenerMethodName)
+ throws IntrospectionException
+ {
+ setName(eventSetName);
+ if (!java.util.EventListener.class.isAssignableFrom(listenerType))
+ {
+ throw new IntrospectionException(
+ "Listener type is not an EventListener.");
+ }
+
+ findMethods(eventSourceClass, listenerType, listenerMethodNames,
+ addListenerMethodName, removeListenerMethodName, null);
+ this.listenerType = listenerType;
+ checkAddListenerUnicast();
+ if (this.removeListenerMethod.getExceptionTypes().length > 0)
+ {
+ throw new IntrospectionException(
+ "Listener remove method throws exceptions.");
+ }
+ }
+
+ /**
+ * Creates a new <code>EventSetDescriptor</code>.
+ *
+ * <p>
+ * This variant of the constructor allows you to specify the names of the
+ * methods and adds no new constraints on top of the rules already described
+ * at the top of the class.
+ * </p>
+ * <p>
+ * A valid GetListener method is public, flags no exceptions and has one
+ * argument which is of type <code>Class</code>
+ * {@link java.awt.Component#getListeners(Class)} is such a method.
+ * </p>
+ * <p>
+ * Note: The validity of the return value of the GetListener method is not
+ * checked.
+ * </p>
+ *
+ * @param eventSourceClass
+ * the class containing the add and remove listener methods.
+ * @param eventSetName
+ * the programmatic name of the event set, generally starting with a
+ * lowercase letter (i.e. fooManChu instead of FooManChu).
+ * @param listenerType
+ * the class containing the event firing methods.
+ * @param listenerMethodNames
+ * the names of the even firing methods.
+ * @param addListenerMethodName
+ * the name of the add listener method.
+ * @param removeListenerMethodName
+ * the name of the remove listener method.
+ * @param getListenerMethodName
+ * Name of a method which returns the array of listeners.
+ * @exception IntrospectionException
+ * if listenerType is not an EventListener or if methods are not
+ * found or are invalid.
+ * @since 1.4
+ */
+ public EventSetDescriptor(Class eventSourceClass, String eventSetName,
+ Class listenerType, String[] listenerMethodNames,
+ String addListenerMethodName,
+ String removeListenerMethodName,
+ String getListenerMethodName)
+ throws IntrospectionException
+ {
+ this(eventSourceClass, eventSetName, listenerType, listenerMethodNames,
+ addListenerMethodName, removeListenerMethodName);
+
+ Method newGetListenerMethod = null;
+
+ try
+ {
+ newGetListenerMethod
+ = eventSourceClass.getMethod(getListenerMethodName,
+ new Class[] { Class.class });
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ throw (IntrospectionException)
+ new IntrospectionException("No method named " + getListenerMethodName
+ + " in class " + listenerType
+ + " which can be used as"
+ + " getListenerMethod.").initCause(nsme);
+ }
+
+ // Note: This does not check the return value (which
+ // should be EventListener[]) but the JDK does not either.
+
+ getListenerMethod = newGetListenerMethod;
+
+ }
+
+ /**
+ * Creates a new <code>EventSetDescriptor.</code>
+ *
+ * <p>
+ * This variant of the constructor allows you to specify the names of the
+ * methods and adds no new constraints on top of the rules already described
+ * at the top of the class.
+ * </p>
+ * <p>
+ * A valid GetListener method is public, flags no exceptions and has one
+ * argument which is of type <code>Class</code>
+ * {@link java.awt.Component#getListeners(Class)} is such a method.
+ * </p>
+ * <p>
+ * Note: The validity of the return value of the GetListener method is not
+ * checked.
+ * </p>
+ *
+ * @param eventSetName
+ * the programmatic name of the event set, generally starting with a
+ * lowercase letter (i.e. fooManChu instead of FooManChu).
+ * @param listenerType
+ * the class containing the listenerMethods.
+ * @param listenerMethods
+ * the event firing methods.
+ * @param addListenerMethod
+ * the add listener method.
+ * @param removeListenerMethod
+ * the remove listener method.
+ * @param getListenerMethod
+ * The method which returns an array of the listeners.
+ * @exception IntrospectionException
+ * if the listenerType is not an EventListener, or any of the
+ * methods are invalid.
+ * @since 1.4
+ */
+ public EventSetDescriptor(String eventSetName, Class listenerType,
+ Method[] listenerMethods, Method addListenerMethod,
+ Method removeListenerMethod,
+ Method getListenerMethod)
+ throws IntrospectionException
+ {
+ this(eventSetName, listenerType, listenerMethods, addListenerMethod,
+ removeListenerMethod);
+
+ // Do no checks if the getListenerMethod is null.
+ if (getListenerMethod.getParameterTypes().length != 1
+ || getListenerMethod.getParameterTypes()[0] != Class.class
+ || getListenerMethod.getExceptionTypes().length > 0
+ || !Modifier.isPublic(getListenerMethod.getModifiers()))
+ throw new IntrospectionException("GetListener method is invalid.");
+
+ // Note: This does not check the return value (which
+ // should be EventListener[]) but the JDK does not either.
+
+ this.getListenerMethod = getListenerMethod;
+ }
+
+ /**
+ * Creates a new <code>EventSetDescriptor</code>.
+ *
+ * <p>This form of constructor allows you to explicitly say which methods
+ * do what, and no reflection is done by the <code>EventSetDescriptor</code>.
+ * The methods are, however, checked to ensure that they follow the rules
+ * set forth at the top of the class.
+ *
+ * @param eventSetName
+ * the programmatic name of the event set, generally starting with a
+ * lowercase letter (i.e. fooManChu instead of FooManChu).
+ * @param listenerType
+ * the class containing the listenerMethods.
+ * @param listenerMethods
+ * the event firing methods.
+ * @param addListenerMethod
+ * the add listener method.
+ * @param removeListenerMethod
+ * the remove listener method.
+ * @exception IntrospectionException
+ * if the listenerType is not an EventListener, or any of the
+ * methods are invalid.
+ */
+ public EventSetDescriptor(String eventSetName, Class listenerType,
+ Method[] listenerMethods, Method addListenerMethod,
+ Method removeListenerMethod)
+ throws IntrospectionException
+ {
+ setName(eventSetName);
+ if (!java.util.EventListener.class.isAssignableFrom(listenerType))
+ {
+ throw new IntrospectionException(
+ "Listener type is not an EventListener.");
+ }
+
+ this.listenerMethods = listenerMethods;
+ this.addListenerMethod = addListenerMethod;
+ this.removeListenerMethod = removeListenerMethod;
+ this.listenerType = listenerType;
+ checkMethods();
+ checkAddListenerUnicast();
+ if (this.removeListenerMethod.getExceptionTypes().length > 0)
+ {
+ throw new IntrospectionException(
+ "Listener remove method throws exceptions.");
+ }
+ }
+
+ /** Creates a new <code>EventSetDescriptor</code>.
+ *
+ * <p>This form of constructor allows you to explicitly say which methods do
+ * what, and no reflection is done by the <code>EventSetDescriptor</code>.
+ * The methods are, however, checked to ensure that they follow the rules
+ * set forth at the top of the class.
+ *
+ * @param eventSetName
+ * the programmatic name of the event set, generally starting with a
+ * lowercase letter (i.e. fooManChu instead of FooManChu).
+ * @param listenerType
+ * the class containing the listenerMethods.
+ * @param listenerMethodDescriptors
+ * the event firing methods.
+ * @param addListenerMethod
+ * the add listener method.
+ * @param removeListenerMethod
+ * the remove listener method.
+ * @exception IntrospectionException
+ * if the listenerType is not an EventListener, or any of the
+ * methods are invalid.
+ */
+ public EventSetDescriptor(String eventSetName, Class listenerType,
+ MethodDescriptor[] listenerMethodDescriptors,
+ Method addListenerMethod,
+ Method removeListenerMethod)
+ throws IntrospectionException
+ {
+ setName(eventSetName);
+ if (!java.util.EventListener.class.isAssignableFrom(listenerType))
+ {
+ throw new IntrospectionException(
+ "Listener type is not an EventListener.");
+ }
+
+ this.listenerMethodDescriptors = listenerMethodDescriptors;
+ this.listenerMethods = new Method[listenerMethodDescriptors.length];
+ for (int i = 0; i < this.listenerMethodDescriptors.length; i++)
+ {
+ this.listenerMethods[i]
+ = this.listenerMethodDescriptors[i].getMethod();
+ }
+
+ this.addListenerMethod = addListenerMethod;
+ this.removeListenerMethod = removeListenerMethod;
+ this.listenerType = listenerType;
+ checkMethods();
+ checkAddListenerUnicast();
+ if (this.removeListenerMethod.getExceptionTypes().length > 0)
+ {
+ throw new IntrospectionException(
+ "Listener remove method throws exceptions.");
+ }
+ }
+
+ /** Returns the class that contains the event firing methods.
+ */
+ public Class getListenerType()
+ {
+ return listenerType;
+ }
+
+ /** Returns the event firing methods.
+ */
+ public Method[] getListenerMethods()
+ {
+ return listenerMethods;
+ }
+
+ /** Returns the event firing methods as {@link MethodDescriptor}.
+ */
+ public MethodDescriptor[] getListenerMethodDescriptors()
+ {
+ if (listenerMethodDescriptors == null)
+ {
+ listenerMethodDescriptors
+ = new MethodDescriptor[listenerMethods.length];
+
+ for (int i = 0; i < listenerMethods.length; i++)
+ {
+ listenerMethodDescriptors[i]
+ = new MethodDescriptor(listenerMethods[i]);
+ }
+ }
+
+ return listenerMethodDescriptors;
+ }
+
+ /** Returns the add listener method.
+ */
+ public Method getAddListenerMethod()
+ {
+ return addListenerMethod;
+ }
+
+ /* Returns the remove listener method.
+ */
+ public Method getRemoveListenerMethod()
+ {
+ return removeListenerMethod;
+ }
+
+ /**
+ * Returns the method that retrieves the listeners or <code>null</code> if
+ * it does not exist.
+ */
+ public Method getGetListenerMethod()
+ {
+ return getListenerMethod;
+ }
+
+ /** Sets whether or not multiple listeners may be added.
+ *
+ * @param unicast
+ * whether or not multiple listeners may be added.
+ */
+ public void setUnicast(boolean unicast)
+ {
+ this.unicast = unicast;
+ }
+
+ /** Returns whether or not multiple listeners may be added.
+ * (Defaults to false.)
+ */
+ public boolean isUnicast()
+ {
+ return unicast;
+ }
+
+ /** Sets whether or not this is in the default event set.
+ *
+ * @param inDefaultEventSet
+ * whether this is in the default event set.
+ */
+ public void setInDefaultEventSet(boolean inDefaultEventSet)
+ {
+ this.inDefaultEventSet = inDefaultEventSet;
+ }
+
+ /** Returns whether or not this is in the default event set.
+ * (Defaults to true.)
+ */
+ public boolean isInDefaultEventSet()
+ {
+ return inDefaultEventSet;
+ }
+
+ private void checkAddListenerUnicast() throws IntrospectionException
+ {
+ Class[] addListenerExceptions = this.addListenerMethod.getExceptionTypes();
+ if (addListenerExceptions.length > 1)
+ {
+ throw new IntrospectionException(
+ "Listener add method throws too many exceptions.");
+ }
+ else if (addListenerExceptions.length == 1
+ && !java.util.TooManyListenersException.class
+ .isAssignableFrom(addListenerExceptions[0]))
+ {
+ throw new IntrospectionException(
+ "Listener add method throws too many exceptions.");
+ }
+ }
+
+ private void checkMethods() throws IntrospectionException
+ {
+ if (!addListenerMethod.getDeclaringClass()
+ .isAssignableFrom(removeListenerMethod.getDeclaringClass())
+ && !removeListenerMethod.getDeclaringClass()
+ .isAssignableFrom(addListenerMethod.getDeclaringClass()))
+ {
+ throw new IntrospectionException(
+ "add and remove listener methods do not come from the"
+ + " same class. This is bad.");
+ }
+ if (!addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
+ || addListenerMethod.getParameterTypes().length != 1
+ || !listenerType.equals(addListenerMethod.getParameterTypes()[0])
+ || !Modifier.isPublic(addListenerMethod.getModifiers()))
+ {
+ throw new IntrospectionException("Add Listener Method invalid.");
+ }
+ if (!removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
+ || removeListenerMethod.getParameterTypes().length != 1
+ || !listenerType.equals(removeListenerMethod.getParameterTypes()[0])
+ || removeListenerMethod.getExceptionTypes().length > 0
+ || !Modifier.isPublic(removeListenerMethod.getModifiers()))
+ {
+ throw new IntrospectionException("Remove Listener Method invalid.");
+ }
+
+ for (int i = 0; i < listenerMethods.length; i++)
+ {
+ if (!listenerMethods[i].getReturnType().equals(java.lang.Void.TYPE)
+ || Modifier.isPrivate(listenerMethods[i].getModifiers()))
+ {
+ throw new IntrospectionException("Event Method "
+ + listenerMethods[i].getName()
+ + " non-void or private.");
+ }
+ if (!listenerMethods[i].getDeclaringClass()
+ .isAssignableFrom(listenerType))
+ {
+ throw new IntrospectionException("Event Method "
+ + listenerMethods[i].getName()
+ + " not from class "
+ + listenerType.getName());
+ }
+ }
+ }
+
+ private void findMethods(Class eventSourceClass, Class listenerType,
+ String listenerMethodNames[],
+ String addListenerMethodName,
+ String removeListenerMethodName,
+ String absurdEventClassCheckName)
+ throws IntrospectionException
+ {
+
+ /* Find add listener method and remove listener method. */
+ Class[] listenerArgList = new Class[1];
+ listenerArgList[0] = listenerType;
+ try
+ {
+ this.addListenerMethod
+ = eventSourceClass.getMethod(addListenerMethodName,
+ listenerArgList);
+ }
+ catch (SecurityException E)
+ {
+ throw new IntrospectionException(
+ "SecurityException trying to access method "
+ + addListenerMethodName + ".");
+ }
+ catch (NoSuchMethodException E)
+ {
+ throw new IntrospectionException("Could not find method "
+ + addListenerMethodName + ".");
+ }
+
+ if (this.addListenerMethod == null
+ || !this.addListenerMethod.getReturnType().equals(java.lang.Void.TYPE))
+ {
+ throw new IntrospectionException(
+ "Add listener method does not exist, is not public,"
+ + " or is not void.");
+ }
+
+ try
+ {
+ this.removeListenerMethod
+ = eventSourceClass.getMethod(removeListenerMethodName,
+ listenerArgList);
+ }
+ catch (SecurityException E)
+ {
+ throw new IntrospectionException(
+ "SecurityException trying to access method "
+ + removeListenerMethodName + ".");
+ }
+ catch (NoSuchMethodException E)
+ {
+ throw new IntrospectionException("Could not find method "
+ + removeListenerMethodName + ".");
+ }
+ if (this.removeListenerMethod == null
+ || !this.removeListenerMethod.getReturnType()
+ .equals(java.lang.Void.TYPE))
+ {
+ throw new IntrospectionException(
+ "Remove listener method does not exist, is not public,"
+ + " or is not void.");
+ }
+
+ /* Find the listener methods. */
+ Method[] methods;
+ try
+ {
+ methods = ClassHelper.getAllMethods(listenerType);
+ }
+ catch (SecurityException E)
+ {
+ throw new IntrospectionException(
+ "Security: You cannot access fields in this class.");
+ }
+
+ Vector chosenMethods = new Vector();
+ boolean[] listenerMethodFound = new boolean[listenerMethodNames.length];
+ for (int i = 0; i < methods.length; i++)
+ {
+ if (Modifier.isPrivate(methods[i].getModifiers()))
+ {
+ continue;
+ }
+ Method currentMethod = methods[i];
+ Class retval = currentMethod.getReturnType();
+ if (retval.equals(java.lang.Void.TYPE))
+ {
+ for (int j = 0; j < listenerMethodNames.length; j++)
+ {
+ if (currentMethod.getName().equals(listenerMethodNames[j])
+ && (absurdEventClassCheckName == null
+ || (currentMethod.getParameterTypes().length == 1
+ && ((currentMethod.getParameterTypes()[0])
+ .getName().equals(absurdEventClassCheckName)
+ || (currentMethod.getParameterTypes()[0])
+ .getName().endsWith("." + absurdEventClassCheckName)))))
+ {
+ chosenMethods.addElement(currentMethod);
+ listenerMethodFound[j] = true;
+ }
+ }
+ }
+ }
+
+ /* Make sure we found all the methods we were looking for. */
+ for (int i = 0; i < listenerMethodFound.length; i++)
+ {
+ if (!listenerMethodFound[i])
+ {
+ throw new IntrospectionException("Could not find event method "
+ + listenerMethodNames[i]);
+ }
+ }
+
+ /* Now that we've chosen the listener methods we want, store them. */
+ this.listenerMethods = new Method[chosenMethods.size()];
+ for (int i = 0; i < chosenMethods.size(); i++)
+ {
+ this.listenerMethods[i] = (Method) chosenMethods.elementAt(i);
+ }
+ }
+
}
diff --git a/java/beans/PersistenceDelegate.java b/java/beans/PersistenceDelegate.java
index 91c02d2b8..a6f715763 100644
--- a/java/beans/PersistenceDelegate.java
+++ b/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/java/beans/PropertyChangeSupport.java b/java/beans/PropertyChangeSupport.java
index 991390b56..e944e1512 100644
--- a/java/beans/PropertyChangeSupport.java
+++ b/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/java/beans/XMLDecoder.java b/java/beans/XMLDecoder.java
index 238fd6bed..7618bb8cb 100644
--- a/java/beans/XMLDecoder.java
+++ b/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/java/beans/XMLEncoder.java b/java/beans/XMLEncoder.java
index f9cbe6396..feff68bd3 100644
--- a/java/beans/XMLEncoder.java
+++ b/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/java/io/InputStream.java b/java/io/InputStream.java
index 03f5d3c48..2934f0034 100644
--- a/java/io/InputStream.java
+++ b/java/io/InputStream.java
@@ -193,10 +193,8 @@ public abstract class InputStream implements Closeable
*/
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/java/io/InputStreamReader.java b/java/io/InputStreamReader.java
index ef8fd4542..936a03c95 100644
--- a/java/io/InputStreamReader.java
+++ b/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/java/io/ObjectInputStream.java b/java/io/ObjectInputStream.java
index 3fff967b4..771222ad5 100644
--- a/java/io/ObjectInputStream.java
+++ b/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.
@@ -563,8 +563,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
@@ -573,9 +572,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;
@@ -1604,7 +1602,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/java/io/ObjectOutputStream.java b/java/io/ObjectOutputStream.java
index 628d0e2b4..063433941 100644
--- a/java/io/ObjectOutputStream.java
+++ b/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.
@@ -427,6 +427,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/java/lang/Character.java b/java/lang/Character.java
index b0535e8b6..35a700d63 100644
--- a/java/lang/Character.java
+++ b/java/lang/Character.java
@@ -1643,6 +1643,290 @@ public final class Character implements Serializable, Comparable<Character>
} // 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
@@ -2126,39 +2410,128 @@ public final class Character implements Serializable, Comparable<Character>
/**
* 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
@@ -2166,14 +2539,32 @@ public final class Character implements Serializable, Comparable<Character>
* @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.
@@ -2200,7 +2591,7 @@ public final class Character implements Serializable, Comparable<Character>
* 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
@@ -2209,10 +2600,11 @@ public final class Character implements Serializable, Comparable<Character>
* @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)];
}
/**
@@ -2285,7 +2677,8 @@ public final class Character implements Serializable, Comparable<Character>
/**
* 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]
*
@@ -2298,12 +2691,34 @@ public final class Character implements Serializable, Comparable<Character>
*/
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]
*
@@ -2316,12 +2731,34 @@ public final class Character implements Serializable, Comparable<Character>
*/
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]
*
@@ -2334,12 +2771,35 @@ public final class Character implements Serializable, Comparable<Character>
*/
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]
*
@@ -2351,7 +2811,28 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2371,12 +2852,37 @@ public final class Character implements Serializable, Comparable<Character>
*/
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]
*
@@ -2394,12 +2900,242 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2419,16 +3155,38 @@ public final class Character implements Serializable, Comparable<Character>
*/
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
@@ -2489,7 +3247,27 @@ public final class Character implements Serializable, Comparable<Character>
*/
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)
@@ -2521,7 +3299,31 @@ public final class Character implements Serializable, Comparable<Character>
*/
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)
@@ -2535,7 +3337,7 @@ public final class Character implements Serializable, Comparable<Character>
| (1 << CURRENCY_SYMBOL)
| (1 << CONNECTOR_PUNCTUATION)
| (1 << FORMAT))) != 0
- || (category == CONTROL && isIdentifierIgnorable(ch));
+ || (category == CONTROL && isIdentifierIgnorable(codePoint));
}
/**
@@ -2554,7 +3356,26 @@ public final class Character implements Serializable, Comparable<Character>
*/
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)
@@ -2583,7 +3404,30 @@ public final class Character implements Serializable, Comparable<Character>
*/
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)
@@ -2596,7 +3440,7 @@ public final class Character implements Serializable, Comparable<Character>
| (1 << LETTER_NUMBER)
| (1 << CONNECTOR_PUNCTUATION)
| (1 << FORMAT))) != 0
- || (category == CONTROL && isIdentifierIgnorable(ch));
+ || (category == CONTROL && isIdentifierIgnorable(codePoint));
}
/**
@@ -2617,9 +3461,33 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2637,8 +3505,37 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2656,8 +3553,37 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2682,6 +3608,30 @@ public final class Character implements Serializable, Comparable<Character>
}
/**
+ * 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
* 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
@@ -2703,20 +3653,68 @@ public final class Character implements Serializable, Comparable<Character>
{
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.
*
@@ -2746,7 +3744,53 @@ public final class Character implements Serializable, Comparable<Character>
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;
}
/**
@@ -2786,7 +3830,23 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
@@ -2811,13 +3871,41 @@ public final class Character implements Serializable, Comparable<Character>
*/
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')
@@ -2842,7 +3930,24 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2884,7 +3989,58 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2941,9 +4097,52 @@ public final class Character implements Serializable, Comparable<Character>
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
@@ -2955,7 +4154,29 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
}
/**
@@ -2980,6 +4201,7 @@ public final class Character implements Serializable, Comparable<Character>
*
* @param val the value to wrap
* @return the <code>Character</code>
+ *
* @since 1.5
*/
public static Character valueOf(char val)
@@ -3018,6 +4240,9 @@ public final class Character implements Serializable, Comparable<Character>
*/
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;
@@ -3235,7 +4460,7 @@ public final class Character implements Serializable, Comparable<Character>
*/
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/java/lang/ClassNotFoundException.java b/java/lang/ClassNotFoundException.java
index 6b6ae949d..142bc5d03 100644
--- a/java/lang/ClassNotFoundException.java
+++ b/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/java/lang/Math.java b/java/lang/Math.java
index 08081e252..d7c8aa1c4 100644
--- a/java/lang/Math.java
+++ b/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 &gt;= <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 &lt;= <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/java/lang/String.java b/java/lang/String.java
index c3c92a178..7a014d431 100644
--- a/java/lang/String.java
+++ b/java/lang/String.java
@@ -559,6 +559,49 @@ public final class String
}
/**
+ * 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
@@ -1824,7 +1867,7 @@ public final class String
*/
private static int upperCaseExpansion(char ch)
{
- return Character.direction[Character.readChar(ch) >> 7] & 3;
+ return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3;
}
/**
@@ -1920,4 +1963,29 @@ public final class String
}
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/java/lang/System.java b/java/lang/System.java
index d6c0609ac..1fb59794f 100644
--- a/java/lang/System.java
+++ b/java/lang/System.java
@@ -190,6 +190,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/java/lang/Thread.java b/java/lang/Thread.java
index e64402610..398a3864b 100644
--- a/java/lang/Thread.java
+++ b/java/lang/Thread.java
@@ -925,7 +925,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/java/lang/reflect/Proxy.java b/java/lang/reflect/Proxy.java
index b1ef7429c..ef743f6bc 100644
--- a/java/lang/reflect/Proxy.java
+++ b/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/java/math/BigDecimal.java b/java/math/BigDecimal.java
index 2726cdf87..6efed91b5 100644
--- a/java/math/BigDecimal.java
+++ b/java/math/BigDecimal.java
@@ -855,16 +855,13 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
// quotients are the same, so compare remainders
- // remove trailing zeros
- if (thisParts[1].equals (BigInteger.ZERO) == false)
- while (thisParts[1].mod (BigInteger.TEN).equals
- (BigInteger.ZERO))
- thisParts[1] = thisParts[1].divide (BigInteger.TEN);
- // again...
- if (valParts[1].equals(BigInteger.ZERO) == false)
- while (valParts[1].mod (BigInteger.TEN).equals
- (BigInteger.ZERO))
- valParts[1] = valParts[1].divide (BigInteger.TEN);
+ // 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/java/net/InetAddress.java b/java/net/InetAddress.java
index 7277331bb..ce65bc773 100644
--- a/java/net/InetAddress.java
+++ b/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/java/net/ServerSocket.java b/java/net/ServerSocket.java
index afc861403..2b889531a 100644
--- a/java/net/ServerSocket.java
+++ b/java/net/ServerSocket.java
@@ -1,5 +1,5 @@
/* ServerSocket.java -- Class for implementing server side sockets
- Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -314,11 +314,6 @@ public class ServerSocket
*/
public Socket accept() throws IOException
{
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkAccept(impl.getInetAddress().getHostAddress(),
- impl.getLocalPort());
-
Socket socket = new Socket();
try
@@ -360,6 +355,9 @@ public class ServerSocket
if (isClosed())
throw new SocketException("ServerSocket is closed");
+ // FIXME: Add a security check to make sure we're allowed to
+ // connect to the remote host.
+
// The Sun spec says that if we have an associated channel and
// it is in non-blocking mode, we throw an IllegalBlockingModeException.
// However, in our implementation if the channel itself initiated this
diff --git a/java/net/SocketPermission.java b/java/net/SocketPermission.java
index 8ccd01bae..723ccc7a5 100644
--- a/java/net/SocketPermission.java
+++ b/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/java/net/URI.java b/java/net/URI.java
index 4ca1f8870..022e4a0f5 100644
--- a/java/net/URI.java
+++ b/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/java/net/URLClassLoader.java b/java/net/URLClassLoader.java
index 02a811d93..702a3de73 100644
--- a/java/net/URLClassLoader.java
+++ b/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/java/net/URLConnection.java b/java/net/URLConnection.java
index 2b727c20d..986270cb2 100644
--- a/java/net/URLConnection.java
+++ b/java/net/URLConnection.java
@@ -599,6 +599,9 @@ public abstract class URLConnection
*/
public void setAllowUserInteraction(boolean allow)
{
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
allowUserInteraction = allow;
}
@@ -777,7 +780,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/java/rmi/AccessException.java b/java/rmi/AccessException.java
index b47078004..40954dfd3 100644
--- a/java/rmi/AccessException.java
+++ b/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/java/rmi/AlreadyBoundException.java b/java/rmi/AlreadyBoundException.java
index 091c0ee58..10f6e4cec 100644
--- a/java/rmi/AlreadyBoundException.java
+++ b/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/java/rmi/MarshalledObject.java b/java/rmi/MarshalledObject.java
index 9ec0ace0e..e1a30f5f0 100644
--- a/java/rmi/MarshalledObject.java
+++ b/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/java/rmi/Naming.java b/java/rmi/Naming.java
index d48df069d..b605da70d 100644
--- a/java/rmi/Naming.java
+++ b/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/java/rmi/NoSuchObjectException.java b/java/rmi/NoSuchObjectException.java
index 69f7d6c52..294390670 100644
--- a/java/rmi/NoSuchObjectException.java
+++ b/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/java/rmi/NotBoundException.java b/java/rmi/NotBoundException.java
index b8bc0a532..03d4adf8f 100644
--- a/java/rmi/NotBoundException.java
+++ b/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/java/rmi/RMISecurityException.java b/java/rmi/RMISecurityException.java
index a44a67e2a..6f15af852 100644
--- a/java/rmi/RMISecurityException.java
+++ b/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/java/rmi/Remote.java b/java/rmi/Remote.java
index 93c8d0aa1..0306981e9 100644
--- a/java/rmi/Remote.java
+++ b/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/java/rmi/RemoteException.java b/java/rmi/RemoteException.java
index cbbb26299..929bc80f6 100644
--- a/java/rmi/RemoteException.java
+++ b/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/java/rmi/StubNotFoundException.java b/java/rmi/StubNotFoundException.java
index 2f9e0f5ff..524b418ce 100644
--- a/java/rmi/StubNotFoundException.java
+++ b/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/java/rmi/package.html b/java/rmi/package.html
index a7bf85020..1d36fe80a 100644
--- a/java/rmi/package.html
+++ b/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/java/rmi/registry/Registry.java b/java/rmi/registry/Registry.java
index 6cd2a04a6..02d8c50cc 100644
--- a/java/rmi/registry/Registry.java
+++ b/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/java/rmi/server/RemoteObjectInvocationHandler.java b/java/rmi/server/RemoteObjectInvocationHandler.java
new file mode 100644
index 000000000..afd1d5927
--- /dev/null
+++ b/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/java/rmi/server/RemoteRef.java b/java/rmi/server/RemoteRef.java
index f33f9d374..8bdb66330 100644
--- a/java/rmi/server/RemoteRef.java
+++ b/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/java/rmi/server/RemoteStub.java b/java/rmi/server/RemoteStub.java
index 18c614b54..d6dff7fad 100644
--- a/java/rmi/server/RemoteStub.java
+++ b/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/java/rmi/server/UnicastRemoteObject.java b/java/rmi/server/UnicastRemoteObject.java
index dbe25bda3..31bf88023 100644
--- a/java/rmi/server/UnicastRemoteObject.java
+++ b/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/java/security/AlgorithmParameterGenerator.java b/java/security/AlgorithmParameterGenerator.java
index 5dc9e3bb2..e33fbaf81 100644
--- a/java/security/AlgorithmParameterGenerator.java
+++ b/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/java/security/AlgorithmParameters.java b/java/security/AlgorithmParameters.java
index 385f15789..911c566c8 100644
--- a/java/security/AlgorithmParameters.java
+++ b/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 <T extends AlgorithmParameterSpec>
T getParameterSpec(Class<T> paramSpec)
@@ -299,13 +266,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
{
@@ -313,15 +277,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
{
@@ -329,10 +294,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/java/security/Identity.java b/java/security/Identity.java
index 7ef59cfe2..c9df0a58f 100644
--- a/java/security/Identity.java
+++ b/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/java/security/IdentityScope.java b/java/security/IdentityScope.java
index 4b19d26e1..610d3534c 100644
--- a/java/security/IdentityScope.java
+++ b/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<Identity> 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/java/security/KeyFactory.java b/java/security/KeyFactory.java
index 3632b3e26..1ecfd2f72 100644
--- a/java/security/KeyFactory.java
+++ b/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 &amp; 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 &amp; 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 &amp; 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 <T extends KeySpec> T getKeySpec(Key key, Class<T> 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/java/security/KeyPairGenerator.java b/java/security/KeyPairGenerator.java
index a6e010be2..357d7a75f 100644
--- a/java/security/KeyPairGenerator.java
+++ b/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 &amp; 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
- * &amp; 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 &amp; 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
- * &amp; 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 &amp; 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/java/security/MessageDigest.java b/java/security/MessageDigest.java
index 8a6af645b..b817759f5 100644
--- a/java/security/MessageDigest.java
+++ b/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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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/java/security/Policy.java b/java/security/Policy.java
index 03d9bbb4e..de1ab80ef 100644
--- a/java/security/Policy.java
+++ b/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>&lt;JAVA_HOME>/lib/security/java.security
- * </code>, where <code>&lt;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/java/security/ProtectionDomain.java b/java/security/ProtectionDomain.java
index a8a093925..33af8fdb8 100644
--- a/java/security/ProtectionDomain.java
+++ b/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/java/security/Security.java b/java/security/Security.java
index d8d746b05..8cc6c8367 100644
--- a/java/security/Security.java
+++ b/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 &amp; 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 &amp; 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<String> 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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;</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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:&lt;attribute_value&gt;</p>
- * <p>The cryptographic service name must not contain any dots. There must
- * be one or more space charaters between the the &lt;algorithm_or_type&gt;
- * and the &lt;attribute_name&gt;.</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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;: 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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:&lt;value&gt;:
+ * 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
- * &amp; 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,49 +495,48 @@ 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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;</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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;</p>
- * <p>The cryptographic service name must not contain any dots. There must
- * be one or more space charaters between the &lt;algorithm_or_type&gt; and
- * the &lt;attribute_name&gt;.</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
- * &amp; 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)
- */
- public static Provider[] getProviders(Map<String, String> filter)
+ /**
+ * 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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;: 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>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:
+ * 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<String,String> filter)
{
if (providers == null || providers.isEmpty())
return null;
diff --git a/java/security/Signature.java b/java/security/Signature.java
index 852c95922..845a77a8b 100644
--- a/java/security/Signature.java
+++ b/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 &amp; 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 &amp; 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 &amp; 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 &amp; 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/java/security/SignatureSpi.java b/java/security/SignatureSpi.java
index 471a73d17..25d49dedd 100644
--- a/java/security/SignatureSpi.java
+++ b/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/java/security/SignedObject.java b/java/security/SignedObject.java
index d565b2ea3..be5a67461 100644
--- a/java/security/SignedObject.java
+++ b/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/java/security/Signer.java b/java/security/Signer.java
index ae1463db8..c7780f6d3 100644
--- a/java/security/Signer.java
+++ b/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/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
index d80b962d0..da7d7479d 100644
--- a/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
+++ b/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/java/security/spec/PSSParameterSpec.java b/java/security/spec/PSSParameterSpec.java
index 7a14a24fb..f2a83d967 100644
--- a/java/security/spec/PSSParameterSpec.java
+++ b/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/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
index 519a02913..9e8ad0da7 100644
--- a/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
+++ b/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/java/security/spec/RSAOtherPrimeInfo.java b/java/security/spec/RSAOtherPrimeInfo.java
index 654bcb574..03cdca227 100644
--- a/java/security/spec/RSAOtherPrimeInfo.java
+++ b/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/java/util/AbstractCollection.java b/java/util/AbstractCollection.java
index a84f221af..7af850b46 100644
--- a/java/util/AbstractCollection.java
+++ b/java/util/AbstractCollection.java
@@ -435,7 +435,9 @@ public abstract class AbstractCollection<E>
* 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
*/
@@ -443,10 +445,16 @@ public abstract class AbstractCollection<E>
{
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/java/util/Hashtable.java b/java/util/Hashtable.java
index 8dfd6215e..37ee03ccc 100644
--- a/java/util/Hashtable.java
+++ b/java/util/Hashtable.java
@@ -1,6 +1,7 @@
/* Hashtable.java -- a class providing a basic hashtable data structure,
mapping Object --> Object
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -110,12 +111,6 @@ public class Hashtable<K, V> extends Dictionary<K, V>
*/
private static final int DEFAULT_CAPACITY = 11;
- /** An "enum" of iterator types. */
- // Package visible for use by nested classes.
- static final int KEYS = 0,
- VALUES = 1,
- ENTRIES = 2;
-
/**
* The default load factor; this is explicitly specified by the spec.
*/
@@ -303,7 +298,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
*/
public Enumeration<K> keys()
{
- return new Enumerator<K>(KEYS);
+ return new KeyEnumerator();
}
/**
@@ -317,7 +312,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
*/
public Enumeration<V> elements()
{
- return new Enumerator<V>(VALUES);
+ return new ValueEnumerator();
}
/**
@@ -334,21 +329,20 @@ public class Hashtable<K, V> extends Dictionary<K, V>
*/
public synchronized boolean contains(Object value)
{
+ if (value == null)
+ throw new NullPointerException();
+
for (int i = buckets.length - 1; i >= 0; i--)
{
HashEntry<K, V> e = buckets[i];
while (e != null)
{
- if (value.equals(e.value))
+ if (e.value.equals(value))
return true;
e = e.next;
}
}
- // Must throw on null argument even if the table is empty
- if (value == null)
- throw new NullPointerException();
-
return false;
}
@@ -386,7 +380,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
HashEntry<K, V> e = buckets[idx];
while (e != null)
{
- if (key.equals(e.key))
+ if (e.key.equals(key))
return true;
e = e.next;
}
@@ -409,7 +403,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
HashEntry<K, V> e = buckets[idx];
while (e != null)
{
- if (key.equals(e.key))
+ if (e.key.equals(key))
return e.value;
e = e.next;
}
@@ -439,7 +433,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
while (e != null)
{
- if (key.equals(e.key))
+ if (e.key.equals(key))
{
// Bypass e.setValue, since we already know value is non-null.
V r = e.value;
@@ -485,7 +479,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
while (e != null)
{
- if (key.equals(e.key))
+ if (e.key.equals(key))
{
modCount++;
if (last == null)
@@ -584,9 +578,8 @@ public class Hashtable<K, V> extends Dictionary<K, V>
{
// Since we are already synchronized, and entrySet().iterator()
// would repeatedly re-lock/release the monitor, we directly use the
- // unsynchronized HashIterator instead.
- Iterator<Map.Entry<? extends K, ? extends V>> entries
- = new HashIterator<Map.Entry<? extends K, ? extends V>>(ENTRIES);
+ // unsynchronized EntryIterator instead.
+ Iterator<Map.Entry<K, V>> entries = new EntryIterator();
StringBuffer r = new StringBuffer("{");
for (int pos = size; pos > 0; pos--)
{
@@ -628,7 +621,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
public Iterator<K> iterator()
{
- return new HashIterator<K>(KEYS);
+ return new KeyIterator();
}
public void clear()
@@ -686,7 +679,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
public Iterator<V> iterator()
{
- return new HashIterator<V>(VALUES);
+ return new ValueIterator();
}
public void clear()
@@ -738,7 +731,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
public Iterator<Map.Entry<K, V>> iterator()
{
- return new HashIterator<Map.Entry<K, V>>(ENTRIES);
+ return new EntryIterator();
}
public void clear()
@@ -782,7 +775,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
*/
public boolean equals(Object o)
{
- // No need to synchronize, entrySet().equals() does that.
+ // no need to synchronize, entrySet().equals() does that.
if (o == this)
return true;
if (!(o instanceof Map))
@@ -802,8 +795,8 @@ public class Hashtable<K, V> extends Dictionary<K, V>
{
// Since we are already synchronized, and entrySet().iterator()
// would repeatedly re-lock/release the monitor, we directly use the
- // unsynchronized HashIterator instead.
- Iterator<Map.Entry<K, V>> itr = new HashIterator<Map.Entry<K, V>>(ENTRIES);
+ // unsynchronized EntryIterator instead.
+ Iterator<Map.Entry<K, V>> itr = new EntryIterator();
int hashcode = 0;
for (int pos = size; pos > 0; pos--)
hashcode += itr.next().hashCode();
@@ -848,7 +841,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
HashEntry<K, V> e = buckets[idx];
while (e != null)
{
- if (o.equals(e))
+ if (e.equals(o))
return e;
e = e.next;
}
@@ -909,8 +902,12 @@ public class Hashtable<K, V> extends Dictionary<K, V>
if (dest != null)
{
- while (dest.next != null)
- dest = dest.next;
+ HashEntry next = dest.next;
+ while (next != null)
+ {
+ dest = next;
+ next = dest.next;
+ }
dest.next = e;
}
else
@@ -945,8 +942,8 @@ public class Hashtable<K, V> extends Dictionary<K, V>
s.writeInt(size);
// Since we are already synchronized, and entrySet().iterator()
// would repeatedly re-lock/release the monitor, we directly use the
- // unsynchronized HashIterator instead.
- Iterator<Map.Entry<K, V>> it = new HashIterator<Map.Entry<K, V>>(ENTRIES);
+ // unsynchronized EntryIterator instead.
+ Iterator<Map.Entry<K, V>> it = new EntryIterator();
while (it.hasNext())
{
HashEntry<K, V> entry = (HashEntry<K, V>) it.next();
@@ -985,22 +982,19 @@ public class Hashtable<K, V> extends Dictionary<K, V>
/**
* A class which implements the Iterator interface and is used for
* iterating over Hashtables.
- * This implementation is parameterized to give a sequential view of
- * keys, values, or entries; it also allows the removal of elements,
- * as per the Javasoft spec. Note that it is not synchronized; this is
- * a performance enhancer since it is never exposed externally and is
- * only used within synchronized blocks above.
+ * This implementation iterates entries. Subclasses are used to
+ * iterate key and values. It also allows the removal of elements,
+ * as per the Javasoft spec. Note that it is not synchronized; this
+ * is a performance enhancer since it is never exposed externally
+ * and is only used within synchronized blocks above.
*
* @author Jon Zeppieri
+ * @author Fridjof Siebert
*/
- private final class HashIterator<T> implements Iterator<T>
+ private class EntryIterator
+ implements Iterator<Entry<K,V>>
{
/**
- * The type of this Iterator: {@link #KEYS}, {@link #VALUES},
- * or {@link #ENTRIES}.
- */
- final int type;
- /**
* The number of modifications to the backing Hashtable that we know about.
*/
int knownMod = modCount;
@@ -1018,14 +1012,13 @@ public class Hashtable<K, V> extends Dictionary<K, V>
HashEntry<K, V> next;
/**
- * Construct a new HashIterator with the supplied type.
- * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
+ * Construct a new EntryIterator
*/
- HashIterator(int type)
+ EntryIterator()
{
- this.type = type;
}
+
/**
* Returns true if the Iterator has more elements.
* @return true if there are more elements
@@ -1044,7 +1037,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
* @throws ConcurrentModificationException if the hashtable was modified
* @throws NoSuchElementException if there is none
*/
- public T next()
+ public Map.Entry<K,V> next()
{
if (knownMod != modCount)
throw new ConcurrentModificationException();
@@ -1054,15 +1047,14 @@ public class Hashtable<K, V> extends Dictionary<K, V>
HashEntry<K, V> e = next;
while (e == null)
- e = buckets[--idx];
+ if (idx <= 0)
+ return null;
+ else
+ e = buckets[--idx];
next = e.next;
last = e;
- if (type == VALUES)
- return (T) e.value;
- if (type == KEYS)
- return (T) e.key;
- return (T) e;
+ return e;
}
/**
@@ -1082,29 +1074,156 @@ public class Hashtable<K, V> extends Dictionary<K, V>
last = null;
knownMod++;
}
- } // class HashIterator
+ } // class EntryIterator
+ /**
+ * A class which implements the Iterator interface and is used for
+ * iterating over keys in Hashtables. This class uses an
+ * <code>EntryIterator</code> to obtain the keys of each entry.
+ *
+ * @author Fridtjof Siebert
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ private class KeyIterator
+ implements Iterator<K>
+ {
+ /**
+ * This entry iterator is used for most operations. Only
+ * <code>next()</code> gives a different result, by returning just
+ * the key rather than the whole element.
+ */
+ private EntryIterator iterator;
+
+ /**
+ * Construct a new KeyIterator
+ */
+ KeyIterator()
+ {
+ iterator = new EntryIterator();
+ }
+
+
+ /**
+ * Returns true if the entry iterator has more elements.
+ *
+ * @return true if there are more elements
+ * @throws ConcurrentModificationException if the hashtable was modified
+ */
+ public boolean hasNext()
+ {
+ return iterator.hasNext();
+ }
+
+ /**
+ * Returns the next element in the Iterator's sequential view.
+ *
+ * @return the next element
+ *
+ * @throws ConcurrentModificationException if the hashtable was modified
+ * @throws NoSuchElementException if there is none
+ */
+ public K next()
+ {
+ return ((HashEntry<K,V>) iterator.next()).key;
+ }
+
+ /**
+ * Removes the last element used by the <code>next()</code> method
+ * using the entry iterator.
+ *
+ * @throws ConcurrentModificationException if the hashtable was modified
+ * @throws IllegalStateException if called when there is no last element
+ */
+ public void remove()
+ {
+ iterator.remove();
+ }
+ } // class KeyIterator
+
/**
- * Enumeration view of this Hashtable, providing sequential access to its
- * elements; this implementation is parameterized to provide access either
- * to the keys or to the values in the Hashtable.
+ * A class which implements the Iterator interface and is used for
+ * iterating over values in Hashtables. This class uses an
+ * <code>EntryIterator</code> to obtain the values of each entry.
+ *
+ * @author Fridtjof Siebert
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ private class ValueIterator
+ implements Iterator<V>
+ {
+
+ /**
+ * This entry iterator is used for most operations. Only
+ * <code>next()</code> gives a different result, by returning just
+ * the value rather than the whole element.
+ */
+ private EntryIterator iterator;
+
+ /**
+ * Construct a new KeyIterator
+ */
+ ValueIterator()
+ {
+ iterator = new EntryIterator();
+ }
+
+
+ /**
+ * Returns true if the entry iterator has more elements.
+ *
+ * @return true if there are more elements
+ * @throws ConcurrentModificationException if the hashtable was modified
+ */
+ public boolean hasNext()
+ {
+ return iterator.hasNext();
+ }
+
+ /**
+ * Returns the value of the next element in the iterator's sequential view.
+ *
+ * @return the next value
+ *
+ * @throws ConcurrentModificationException if the hashtable was modified
+ * @throws NoSuchElementException if there is none
+ */
+ public V next()
+ {
+ return ((HashEntry<K,V>) iterator.next()).value;
+ }
+
+ /**
+ * Removes the last element used by the <code>next()</code> method
+ * using the entry iterator.
+ *
+ * @throws ConcurrentModificationException if the hashtable was modified
+ * @throws IllegalStateException if called when there is no last element
+ */
+ public void remove()
+ {
+ iterator.remove();
+ }
+
+ } // class ValueIterator
+
+ /**
+ * Enumeration view of the entries in this Hashtable, providing
+ * sequential access to its elements.
*
* <b>NOTE</b>: Enumeration is not safe if new elements are put in the table
* as this could cause a rehash and we'd completely lose our place. Even
* without a rehash, it is undetermined if a new element added would
* appear in the enumeration. The spec says nothing about this, but
- * the "Java Class Libraries" book infers that modifications to the
+ * the "Java Class Libraries" book implies that modifications to the
* hashtable during enumeration causes indeterminate results. Don't do it!
*
* @author Jon Zeppieri
+ * @author Fridjof Siebert
*/
- private final class Enumerator<T> implements Enumeration<T>
+ private class EntryEnumerator
+ implements Enumeration<Entry<K,V>>
{
- /**
- * The type of this Iterator: {@link #KEYS} or {@link #VALUES}.
- */
- final int type;
/** The number of elements remaining to be returned by next(). */
int count = size;
/** Current index in the physical hash table. */
@@ -1118,11 +1237,10 @@ public class Hashtable<K, V> extends Dictionary<K, V>
/**
* Construct the enumeration.
- * @param type either {@link #KEYS} or {@link #VALUES}.
*/
- Enumerator(int type)
+ EntryEnumerator()
{
- this.type = type;
+ // Nothing to do here.
}
/**
@@ -1139,7 +1257,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
* @return the next element
* @throws NoSuchElementException if there is none.
*/
- public T nextElement()
+ public Map.Entry<K,V> nextElement()
{
if (count == 0)
throw new NoSuchElementException("Hashtable Enumerator");
@@ -1147,10 +1265,136 @@ public class Hashtable<K, V> extends Dictionary<K, V>
HashEntry<K, V> e = next;
while (e == null)
- e = buckets[--idx];
+ if (idx <= 0)
+ return null;
+ else
+ e = buckets[--idx];
next = e.next;
- return type == VALUES ? (T) e.value : (T) e.key;
+ return e;
+ }
+ } // class EntryEnumerator
+
+
+ /**
+ * Enumeration view of this Hashtable, providing sequential access to its
+ * elements.
+ *
+ * <b>NOTE</b>: Enumeration is not safe if new elements are put in the table
+ * as this could cause a rehash and we'd completely lose our place. Even
+ * without a rehash, it is undetermined if a new element added would
+ * appear in the enumeration. The spec says nothing about this, but
+ * the "Java Class Libraries" book implies that modifications to the
+ * hashtable during enumeration causes indeterminate results. Don't do it!
+ *
+ * @author Jon Zeppieri
+ * @author Fridjof Siebert
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ private final class KeyEnumerator
+ implements Enumeration<K>
+ {
+ /**
+ * This entry enumerator is used for most operations. Only
+ * <code>nextElement()</code> gives a different result, by returning just
+ * the key rather than the whole element.
+ */
+ private EntryEnumerator enumerator;
+
+ /**
+ * Construct a new KeyEnumerator
+ */
+ KeyEnumerator()
+ {
+ enumerator = new EntryEnumerator();
+ }
+
+
+ /**
+ * Returns true if the entry enumerator has more elements.
+ *
+ * @return true if there are more elements
+ * @throws ConcurrentModificationException if the hashtable was modified
+ */
+ public boolean hasMoreElements()
+ {
+ return enumerator.hasMoreElements();
+ }
+
+ /**
+ * Returns the next element.
+ * @return the next element
+ * @throws NoSuchElementException if there is none.
+ */
+ public K nextElement()
+ {
+ HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement();
+ K retVal = null;
+ if (entry != null)
+ retVal = entry.key;
+ return retVal;
+ }
+ } // class KeyEnumerator
+
+
+ /**
+ * Enumeration view of this Hashtable, providing sequential access to its
+ * values.
+ *
+ * <b>NOTE</b>: Enumeration is not safe if new elements are put in the table
+ * as this could cause a rehash and we'd completely lose our place. Even
+ * without a rehash, it is undetermined if a new element added would
+ * appear in the enumeration. The spec says nothing about this, but
+ * the "Java Class Libraries" book implies that modifications to the
+ * hashtable during enumeration causes indeterminate results. Don't do it!
+ *
+ * @author Jon Zeppieri
+ * @author Fridjof Siebert
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+ private final class ValueEnumerator
+ implements Enumeration<V>
+ {
+ /**
+ * This entry enumerator is used for most operations. Only
+ * <code>nextElement()</code> gives a different result, by returning just
+ * the value rather than the whole element.
+ */
+ private EntryEnumerator enumerator;
+
+ /**
+ * Construct a new ValueEnumerator
+ */
+ ValueEnumerator()
+ {
+ enumerator = new EntryEnumerator();
}
- } // class Enumerator
+
+
+ /**
+ * Returns true if the entry enumerator has more elements.
+ *
+ * @return true if there are more elements
+ * @throws ConcurrentModificationException if the hashtable was modified
+ */
+ public boolean hasMoreElements()
+ {
+ return enumerator.hasMoreElements();
+ }
+
+ /**
+ * Returns the next element.
+ * @return the next element
+ * @throws NoSuchElementException if there is none.
+ */
+ public V nextElement()
+ {
+ HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement();
+ V retVal = null;
+ if (entry != null)
+ retVal = entry.value;
+ return retVal;
+ }
+ } // class ValueEnumerator
+
} // class Hashtable
diff --git a/java/util/logging/LogManager.java b/java/util/logging/LogManager.java
index 420c97e59..5897a12af 100644
--- a/java/util/logging/LogManager.java
+++ b/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/java/util/logging/SimpleFormatter.java b/java/util/logging/SimpleFormatter.java
index ff53db8c0..2ebb1a148 100644
--- a/java/util/logging/SimpleFormatter.java
+++ b/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/java/util/regex/MatchResult.java b/java/util/regex/MatchResult.java
new file mode 100644
index 000000000..c82d8cc99
--- /dev/null
+++ b/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/java/util/regex/Matcher.java b/java/util/regex/Matcher.java
index 5d04bdbfc..98086bfdb 100644
--- a/java/util/regex/Matcher.java
+++ b/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/java/util/regex/PatternSyntaxException.java b/java/util/regex/PatternSyntaxException.java
index 0c80e119c..41e650d32 100644
--- a/java/util/regex/PatternSyntaxException.java
+++ b/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/java/util/zip/ZipConstants.java b/java/util/zip/ZipConstants.java
index 952a44def..6d664196a 100644
--- a/java/util/zip/ZipConstants.java
+++ b/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/java/util/zip/ZipFile.java b/java/util/zip/ZipFile.java
index 1bc66e267..75a466a5f 100644
--- a/java/util/zip/ZipFile.java
+++ b/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<String, ZipEntry> (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/java/util/zip/ZipOutputStream.java b/java/util/zip/ZipOutputStream.java
index 5c593b2c4..d292f7d40 100644
--- a/java/util/zip/ZipOutputStream.java
+++ b/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