summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2006-06-27 20:01:40 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2006-06-27 20:01:40 +0000
commit3b00aa20227be4b0f2314278dcea3ef3739c44aa (patch)
treef7d11ad3bf3342c619595f748dbb91b184b8324c /java
parent78c2fbfb5f722402791ad87028a3a5f62ed4c086 (diff)
downloadclasspath-3b00aa20227be4b0f2314278dcea3ef3739c44aa.tar.gz
2006-06-27 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge of HEAD --> generics-branch for 2006/06/16 to 2006/06/27.
Diffstat (limited to 'java')
-rw-r--r--java/awt/Component.java142
-rw-r--r--java/awt/Container.java2
-rw-r--r--java/awt/GridBagConstraints.java139
-rw-r--r--java/awt/GridBagLayout.java217
-rw-r--r--java/awt/Insets.java7
-rw-r--r--java/awt/Label.java434
-rw-r--r--java/awt/List.java18
-rw-r--r--java/awt/Point.java13
-rw-r--r--java/awt/TextField.java10
-rw-r--r--java/awt/Toolkit.java8
-rw-r--r--java/awt/datatransfer/Clipboard.java8
-rw-r--r--java/awt/datatransfer/DataFlavor.java114
-rw-r--r--java/awt/event/KeyEvent.java21
-rw-r--r--java/awt/font/FontRenderContext.java10
-rw-r--r--java/awt/font/LineBreakMeasurer.java107
-rw-r--r--java/awt/font/TextLayout.java225
-rw-r--r--java/awt/font/TextMeasurer.java147
-rw-r--r--java/awt/image/BufferedImage.java5
-rw-r--r--java/lang/Thread.java15
-rw-r--r--java/lang/management/ClassLoadingMXBean.java103
-rw-r--r--java/lang/management/ManagementFactory.java35
-rw-r--r--java/lang/management/OperatingSystemMXBean.java2
-rw-r--r--java/lang/management/RuntimeMXBean.java2
-rw-r--r--java/lang/management/ThreadInfo.java405
-rw-r--r--java/lang/management/ThreadMXBean.java497
-rw-r--r--java/net/URL.java12
-rw-r--r--java/rmi/server/UID.java30
-rw-r--r--java/security/cert/X509CertSelector.java4
-rw-r--r--java/text/AttributedString.java11
-rw-r--r--java/util/logging/LogManager.java76
-rw-r--r--java/util/logging/LoggingMXBean.java85
31 files changed, 2295 insertions, 609 deletions
diff --git a/java/awt/Component.java b/java/awt/Component.java
index 26df1554f..0a987ee3b 100644
--- a/java/awt/Component.java
+++ b/java/awt/Component.java
@@ -70,6 +70,7 @@ import java.awt.image.ImageProducer;
import java.awt.image.VolatileImage;
import java.awt.peer.ComponentPeer;
import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
@@ -427,6 +428,24 @@ public abstract class Component
Dimension minSize;
/**
+ * Flag indicating whether the minimum size for the component has been set
+ * by a call to {@link #setMinimumSize(Dimension)} with a non-null value.
+ */
+ boolean minSizeSet;
+
+ /**
+ * The maximum size for the component.
+ * @see #setMaximumSize(Dimension)
+ */
+ Dimension maxSize;
+
+ /**
+ * A flag indicating whether the maximum size for the component has been set
+ * by a call to {@link #setMaximumSize(Dimension)} with a non-null value.
+ */
+ boolean maxSizeSet;
+
+ /**
* Cached information on the preferred size. Should have been transient.
*
* @serial ignore
@@ -434,6 +453,12 @@ public abstract class Component
Dimension prefSize;
/**
+ * Flag indicating whether the preferred size for the component has been set
+ * by a call to {@link #setPreferredSize(Dimension)} with a non-null value.
+ */
+ boolean prefSizeSet;
+
+ /**
* Set to true if an event is to be handled by this component, false if
* it is to be passed up the hierarcy.
*
@@ -607,16 +632,19 @@ public abstract class Component
}
/**
- * Sets the name of this component to the specified name.
+ * Sets the name of this component to the specified name (this is a bound
+ * property with the name 'name').
*
- * @param name the new name of this component
+ * @param name the new name (<code>null</code> permitted).
* @see #getName()
* @since 1.1
*/
public void setName(String name)
{
nameExplicitlySet = true;
+ String old = this.name;
this.name = name;
+ firePropertyChange("name", old, name);
}
/**
@@ -1584,6 +1612,7 @@ public abstract class Component
*
* @return the component's preferred size
* @see #getMinimumSize()
+ * @see #setPreferredSize(Dimension)
* @see LayoutManager
*/
public Dimension getPreferredSize()
@@ -1592,6 +1621,40 @@ public abstract class Component
}
/**
+ * Sets the preferred size that will be returned by
+ * {@link #getPreferredSize()} always, and sends a
+ * {@link PropertyChangeEvent} (with the property name 'preferredSize') to
+ * all registered listeners.
+ *
+ * @param size the preferred size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getPreferredSize()
+ */
+ public void setPreferredSize(Dimension size)
+ {
+ Dimension old = prefSizeSet ? prefSize : null;
+ prefSize = size;
+ prefSizeSet = (size != null);
+ firePropertyChange("preferredSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current preferred size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setPreferredSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isPreferredSizeSet()
+ {
+ return prefSizeSet;
+ }
+
+ /**
* Returns the component's preferred size.
*
* @return the component's preferred size
@@ -1599,7 +1662,7 @@ public abstract class Component
*/
public Dimension preferredSize()
{
- if (prefSize == null)
+ if (!prefSizeSet)
{
if (peer == null)
prefSize = minimumSize();
@@ -1614,6 +1677,7 @@ public abstract class Component
*
* @return the component's minimum size
* @see #getPreferredSize()
+ * @see #setMinimumSize(Dimension)
* @see LayoutManager
*/
public Dimension getMinimumSize()
@@ -1622,6 +1686,39 @@ public abstract class Component
}
/**
+ * Sets the minimum size that will be returned by {@link #getMinimumSize()}
+ * always, and sends a {@link PropertyChangeEvent} (with the property name
+ * 'minimumSize') to all registered listeners.
+ *
+ * @param size the minimum size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getMinimumSize()
+ */
+ public void setMinimumSize(Dimension size)
+ {
+ Dimension old = minSizeSet ? minSize : null;
+ minSize = size;
+ minSizeSet = (size != null);
+ firePropertyChange("minimumSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current minimum size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setMinimumSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isMinimumSizeSet()
+ {
+ return minSizeSet;
+ }
+
+ /**
* Returns the component's minimum size.
*
* @return the component's minimum size
@@ -1640,15 +1737,52 @@ public abstract class Component
*
* @return the component's maximum size
* @see #getMinimumSize()
+ * @see #setMaximumSize(Dimension)
* @see #getPreferredSize()
* @see LayoutManager
*/
public Dimension getMaximumSize()
{
- return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
+ if (maxSizeSet)
+ return maxSize;
+ else
+ return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
}
/**
+ * Sets the maximum size that will be returned by {@link #getMaximumSize()}
+ * always, and sends a {@link PropertyChangeEvent} (with the property name
+ * 'maximumSize') to all registered listeners.
+ *
+ * @param size the maximum size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getMaximumSize()
+ */
+ public void setMaximumSize(Dimension size)
+ {
+ Dimension old = maxSizeSet ? maxSize : null;
+ maxSize = size;
+ maxSizeSet = (size != null);
+ firePropertyChange("maximumSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current maximum size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setMaximumSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isMaximumSizeSet()
+ {
+ return maxSizeSet;
+ }
+
+ /**
* Returns the preferred horizontal alignment of this component. The value
* returned will be between {@link #LEFT_ALIGNMENT} and
* {@link #RIGHT_ALIGNMENT}, inclusive.
diff --git a/java/awt/Container.java b/java/awt/Container.java
index f145d5696..3f3abc5c7 100644
--- a/java/awt/Container.java
+++ b/java/awt/Container.java
@@ -1688,7 +1688,7 @@ public class Container extends Component
int index = -1;
if (component != null)
{
- for (int i = 0; i < component.length; i++)
+ for (int i = 0; i < ncomponents; i++)
{
if (component[i] == comp)
{
diff --git a/java/awt/GridBagConstraints.java b/java/awt/GridBagConstraints.java
index 8d8b4fae5..a6a64c3bb 100644
--- a/java/awt/GridBagConstraints.java
+++ b/java/awt/GridBagConstraints.java
@@ -48,62 +48,99 @@ public class GridBagConstraints implements Cloneable, Serializable
{
static final long serialVersionUID = -1000070633030801713L;
- /** Fill in both directions. */
- public static final int BOTH = 1;
- /** Don't fill. */
+ // Fill values.
+ /**
+ * Don't fill.
+ */
public static final int NONE = 0;
- /** Fill horizontally. */
+
+ /**
+ * Fill in both directions.
+ */
+ public static final int BOTH = 1;
+
+ /**
+ * Fill horizontally.
+ */
public static final int HORIZONTAL = 2;
- /** Fill vertically. */
+
+ /**
+ * Fill vertically.
+ */
public static final int VERTICAL = 3;
- /** Position in the center. */
+ // Anchor values.
+ /**
+ * Position in the center.
+ */
public static final int CENTER = 10;
- /** Position to the east. */
- public static final int EAST = 13;
- /** Position to the north. */
+
+ /**
+ * Position to the north.
+ */
public static final int NORTH = 11;
- /** Position to the northeast. */
+
+ /**
+ * Position to the northeast.
+ */
public static final int NORTHEAST = 12;
- /** Position to the northwest. */
- public static final int NORTHWEST = 18;
- /** Position to the south. */
- public static final int SOUTH = 15;
- /** Position to the southeast. */
+
+ /**
+ * Position to the east.
+ */
+ public static final int EAST = 13;
+
+ /**
+ * Position to the southeast.
+ */
public static final int SOUTHEAST = 14;
- /** Position to the southwest. */
+
+ /**
+ * Position to the south.
+ */
+ public static final int SOUTH = 15;
+
+ /**
+ * Position to the southwest.
+ */
public static final int SOUTHWEST = 16;
- /** Position to the west. */
+
+ /**
+ * Position to the west.
+ */
public static final int WEST = 17;
- /** Occupy all remaining cells except last cell. */
+ /**
+ * Position to the northwest.
+ */
+ public static final int NORTHWEST = 18;
+
+ // gridx and gridy values.
+ /**
+ * Occupy all remaining cells except last cell.
+ */
public static final int RELATIVE = -1;
- /** Occupy all remaining cells. */
- public static final int REMAINDER = 0;
/**
- * Position to where the first text line would end. Equals to NORTHEAST for
- * horizontal left-to-right orientations.
+ * Occupy all remaining cells.
*/
- public static final int FIRST_LINE_END = 24;
+ public static final int REMAINDER = 0;
/**
- * Position to where the first text line would start. Equals to NORTHWEST for
- * horizontal left-to-right orientations.
+ * Position to where a page starts. Equals NORTH for horizontal orientations.
*/
- public static final int FIRST_LINE_START = 23;
+ public static final int PAGE_START = 19;
/**
- * Position to where the last text line would end. Equals to SOUTHEAST for
- * horizontal left-to-right orientations.
+ * Position to where a page ends. Equals SOUTH for horizontal orientations.
*/
- public static final int LAST_LINE_END = 26;
+ public static final int PAGE_END = 20;
/**
- * Position to where the last text line would start. Equals to SOUTHWEST for
- * horizontal left-to-right orientations.
+ * Position to where a text line would start. Equals to WEST for
+ * left-to-right orientations.
*/
- public static final int LAST_LINE_START = 25;
+ public static final int LINE_START = 21;
/**
* Position to where a text line would end. Equals to EAST for
@@ -112,20 +149,28 @@ public class GridBagConstraints implements Cloneable, Serializable
public static final int LINE_END = 22;
/**
- * Position to where a text line would start. Equals to WEST for
- * left-to-right orientations.
+ * Position to where the first text line would start. Equals to NORTHWEST for
+ * horizontal left-to-right orientations.
*/
- public static final int LINE_START = 21;
+ public static final int FIRST_LINE_START = 23;
/**
- * Position to where a page ends. Equals SOUTH for horizontal orientations.
+ * Position to where the first text line would end. Equals to NORTHEAST for
+ * horizontal left-to-right orientations.
*/
- public static final int PAGE_END = 20;
+ public static final int FIRST_LINE_END = 24;
/**
- * Position to where a page starts. Equals NORTH for horizontal orientations.
+ * Position to where the last text line would start. Equals to SOUTHWEST for
+ * horizontal left-to-right orientations.
*/
- public static final int PAGE_START = 19;
+ public static final int LAST_LINE_START = 25;
+
+ /**
+ * Position to where the last text line would end. Equals to SOUTHEAST for
+ * horizontal left-to-right orientations.
+ */
+ public static final int LAST_LINE_END = 26;
public int anchor;
public int fill;
@@ -139,7 +184,9 @@ public class GridBagConstraints implements Cloneable, Serializable
public double weightx;
public double weighty;
- /** Create a copy of this object. */
+ /**
+ * Create a copy of this object.
+ */
public Object clone ()
{
try
@@ -155,8 +202,10 @@ public class GridBagConstraints implements Cloneable, Serializable
}
}
- /** Create a new GridBagConstraints object with the default
- * parameters. */
+ /**
+ * Create a new GridBagConstraints object with the default
+ * parameters.
+ */
public GridBagConstraints ()
{
this.anchor = CENTER;
@@ -172,8 +221,10 @@ public class GridBagConstraints implements Cloneable, Serializable
this.weighty = 0;
}
- /** Create a new GridBagConstraints object with the indicated
- * parameters. */
+ /**
+ * Create a new GridBagConstraints object with the indicated
+ * parameters.
+ */
public GridBagConstraints (int gridx, int gridy,
int gridwidth, int gridheight,
double weightx, double weighty,
diff --git a/java/awt/GridBagLayout.java b/java/awt/GridBagLayout.java
index 20c402b78..c8d204396 100644
--- a/java/awt/GridBagLayout.java
+++ b/java/awt/GridBagLayout.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package java.awt;
-import gnu.classpath.NotImplementedException;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
@@ -323,13 +321,127 @@ public class GridBagLayout
}
/**
- * Obsolete.
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
*/
- protected void AdjustForGravity (GridBagConstraints gbc, Rectangle rect)
- throws NotImplementedException
+ protected void AdjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
{
- // FIXME
- throw new Error ("Not implemented");
+ Rectangle result = new Rectangle (0, 0, 0, 0);
+
+ // Calculate width and height.
+
+ // Adjust width and height for fill value.
+ switch (constraints.fill)
+ {
+ case GridBagConstraints.NONE:
+ result.width = 0;
+ result.height = 0;
+ break;
+ case GridBagConstraints.BOTH:
+ result.width = r.width;
+ result.height = r.height;
+ break;
+ case GridBagConstraints.HORIZONTAL:
+ result.width = r.width;
+ result.height = 0;
+ break;
+ case GridBagConstraints.VERTICAL:
+ result.width = 0;
+ result.height = r.height;
+ break;
+ }
+
+ // Adjust width and height for insets, and clamp to minimum
+ // values of ipadx and ipady.
+ result.width = Math.max(result.width
+ - constraints.insets.left
+ - constraints.insets.right,
+ constraints.ipadx);
+ result.height = Math.max(result.height
+ - constraints.insets.top
+ - constraints.insets.bottom,
+ constraints.ipady);
+
+ // Calculate x and y.
+
+ // Do not account for the internal padding when setting the
+ // result rectangle's x and y co-ordinates.
+ int rect_width = r.width - constraints.ipadx;
+ int rect_height = r.height - constraints.ipady;
+
+ int half_width = (rect_width + constraints.insets.left
+ - constraints.insets.right) / 2;
+ int half_height = (rect_height + constraints.insets.top
+ - constraints.insets.bottom) / 2;
+
+ // Adjust x and y for anchor value.
+ switch (constraints.anchor)
+ {
+ case GridBagConstraints.CENTER:
+ result.x = r.x + half_width;
+ result.y = r.y + half_height;
+ break;
+ case GridBagConstraints.NORTH:
+ result.x = r.x + half_width;
+ result.y = r.y + constraints.insets.top;
+ break;
+ case GridBagConstraints.NORTHEAST:
+ result.x = r.x + rect_width - constraints.insets.right;
+ result.y = r.y + constraints.insets.top;
+ break;
+ case GridBagConstraints.EAST:
+ result.x = r.x + rect_width - constraints.insets.right;
+ result.y = r.y + half_height;
+ break;
+ case GridBagConstraints.SOUTHEAST:
+ result.x = r.x + rect_width - constraints.insets.right;
+ result.y = r.y + rect_height - constraints.insets.bottom;
+ break;
+ case GridBagConstraints.SOUTH:
+ result.x = r.x + half_width;
+ result.y = r.y + rect_height - constraints.insets.bottom;
+ break;
+ case GridBagConstraints.SOUTHWEST:
+ result.x = r.x + constraints.insets.left;
+ result.y = r.y + rect_height - constraints.insets.bottom;
+ break;
+ case GridBagConstraints.WEST:
+ result.x = r.x + constraints.insets.left;
+ result.y = r.y + half_height;
+ break;
+ case GridBagConstraints.NORTHWEST:
+ result.x = r.x + constraints.insets.left;
+ result.y = r.y + constraints.insets.top;
+ break;
+ }
+
+ // Adjust x and y for fill, clamping values to the external
+ // padding boundaries where necessary.
+ switch (constraints.fill)
+ {
+ case GridBagConstraints.NONE:
+ break;
+ case GridBagConstraints.BOTH:
+ result.x = r.x + constraints.insets.left;
+ result.y = r.y + constraints.insets.top;
+ break;
+ case GridBagConstraints.HORIZONTAL:
+ result.x = r.x + constraints.insets.left;
+ break;
+ case GridBagConstraints.VERTICAL:
+ result.y = r.y + constraints.insets.top;
+ break;
+ }
+
+ r.x = result.x;
+ r.y = result.y;
+ r.width = result.width;
+ r.height = result.height;
}
/**
@@ -354,10 +466,9 @@ public class GridBagLayout
// layoutInfo. So we wait until after this for loop to set
// layoutInfo.
Component lastComp = null;
- int cellx = 0;
- int celly = 0;
- int cellw = 0;
- int cellh = 0;
+
+ Rectangle cell = new Rectangle();
+
for (int i = 0; i < components.length; i++)
{
Component component = components[i];
@@ -371,29 +482,23 @@ public class GridBagLayout
if (lastComp != null
&& constraints.gridheight == GridBagConstraints.REMAINDER)
- celly += cellh;
+ cell.y += cell.height;
else
- celly = sumIntArray(info.rowHeights, constraints.gridy);
+ cell.y = sumIntArray(info.rowHeights, constraints.gridy);
if (lastComp != null
&& constraints.gridwidth == GridBagConstraints.REMAINDER)
- cellx += cellw;
+ cell.x += cell.width;
else
- cellx = sumIntArray(info.colWidths, constraints.gridx);
+ cell.x = sumIntArray(info.colWidths, constraints.gridx);
- cellw = sumIntArray(info.colWidths, constraints.gridx
- + constraints.gridwidth) - cellx;
- cellh = sumIntArray(info.rowHeights, constraints.gridy
- + constraints.gridheight) - celly;
-
- Insets insets = constraints.insets;
- if (insets != null)
- {
- cellx += insets.left;
- celly += insets.top;
- cellw -= insets.left + insets.right;
- cellh -= insets.top + insets.bottom;
- }
+ cell.width = sumIntArray(info.colWidths, constraints.gridx
+ + constraints.gridwidth) - cell.x;
+ cell.height = sumIntArray(info.rowHeights, constraints.gridy
+ + constraints.gridheight) - cell.y;
+
+ // Adjust for insets.
+ AdjustForGravity( constraints, cell );
// Note: Documentation says that padding is added on both sides, but
// visual inspection shows that the Sun implementation only adds it
@@ -404,14 +509,14 @@ public class GridBagLayout
switch (constraints.fill)
{
case GridBagConstraints.HORIZONTAL:
- dim.width = cellw;
+ dim.width = cell.width;
break;
case GridBagConstraints.VERTICAL:
- dim.height = cellh;
+ dim.height = cell.height;
break;
case GridBagConstraints.BOTH:
- dim.width = cellw;
- dim.height = cellh;
+ dim.width = cell.width;
+ dim.height = cell.height;
break;
}
@@ -421,40 +526,40 @@ public class GridBagLayout
switch (constraints.anchor)
{
case GridBagConstraints.NORTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y;
break;
case GridBagConstraints.SOUTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + cellh - dim.height;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.WEST:
- x = cellx;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.EAST:
- x = cellx + cellw - dim.width;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.NORTHEAST:
- x = cellx + cellw - dim.width;
- y = celly;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y;
break;
case GridBagConstraints.NORTHWEST:
- x = cellx;
- y = celly;
+ x = cell.x;
+ y = cell.y;
break;
case GridBagConstraints.SOUTHEAST:
- x = cellx + cellw - dim.width;
- y = celly + cellh - dim.height;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.SOUTHWEST:
- x = cellx;
- y = celly + cellh - dim.height;
+ x = cell.x;
+ y = cell.y + cell.height - dim.height;
break;
default:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
}
component.setBounds(info.pos_x + x, info.pos_y + y, dim.width,
@@ -1086,10 +1191,18 @@ public class GridBagLayout
}
/**
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
+ *
* @since 1.4
*/
- protected void adjustForGravity (GridBagConstraints gbc, Rectangle rect)
+ protected void adjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
{
- AdjustForGravity (gbc, rect);
+ AdjustForGravity (constraints, r);
}
}
diff --git a/java/awt/Insets.java b/java/awt/Insets.java
index 6d5bd122e..762b6975b 100644
--- a/java/awt/Insets.java
+++ b/java/awt/Insets.java
@@ -1,5 +1,5 @@
/* Insets.java -- information about a container border
- Copyright (C) 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -149,14 +149,13 @@ public class Insets implements Cloneable, Serializable
/**
* Returns a string representation of this object, which will be non-null.
- * The format is unspecified, but appears to be <code>XXX what is it?</code>.
*
* @return a string representation of this object
*/
public String toString()
{
- return getClass().getName() + "(top=" + top + ",bottom=" + bottom +
- ",left=" + left + ",right=" + right + ')';
+ return getClass().getName() + "[top=" + top + ",left=" + left
+ + ",bottom=" + bottom + ",right=" + right + ']';
}
/**
diff --git a/java/awt/Label.java b/java/awt/Label.java
index d6db32910..71614da64 100644
--- a/java/awt/Label.java
+++ b/java/awt/Label.java
@@ -1,5 +1,6 @@
/* Label.java -- Java label widget
- 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.
@@ -45,275 +46,250 @@ import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
/**
- * This component is used for displaying simple text strings that cannot
- * be edited by the user.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
- */
+ * This component is used for displaying simple text strings that cannot
+ * be edited by the user.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
public class Label extends Component implements Accessible
{
-/*
- * Static Variables
- */
-
-/**
- * Alignment constant aligning the text to the left of its window.
- */
-public static final int LEFT = 0;
-
-/**
- * Alignment constant aligning the text in the center of its window.
- */
-public static final int CENTER = 1;
-
-/**
- * Alignment constant aligning the text to the right of its window.
- */
-public static final int RIGHT = 2;
-
-// Serialization version constant:
-private static final long serialVersionUID = 3094126758329070636L;
-
-/*************************************************************************/
+ /**
+ * Alignment constant aligning the text to the left of its window.
+ */
+ public static final int LEFT = 0;
-/*
- * Instance Variables
- */
+ /**
+ * Alignment constant aligning the text in the center of its window.
+ */
+ public static final int CENTER = 1;
-/**
- * @serial Indicates the alignment of the text within this label's window.
- * This is one of the constants in this class. The default value is
- * <code>LEFT</code>.
- */
-private int alignment;
+ /**
+ * Alignment constant aligning the text to the right of its window.
+ */
+ public static final int RIGHT = 2;
-/**
- * @serial The text displayed in the label
- */
-private String text;
+ // Serialization version constant:
+ private static final long serialVersionUID = 3094126758329070636L;
-/*************************************************************************/
+ /**
+ * @serial Indicates the alignment of the text within this label's window.
+ * This is one of the constants in this class. The default value is
+ * <code>LEFT</code>.
+ */
+ private int alignment;
-/*
- * Constructors
- */
+ /**
+ * @serial The text displayed in the label
+ */
+ private String text;
-/**
- * Initializes a new instance of <code>Label</code> with no text.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
- */
-public
-Label()
-{
- this("", LEFT);
-}
+ /**
+ * Initializes a new instance of <code>Label</code> with no text.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Label()
+ {
+ this("", LEFT);
+ }
-/*************************************************************************/
+ /**
+ * Initializes a new instance of <code>Label</code> with the specified
+ * text that is aligned to the left.
+ *
+ * @param text The text of the label.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Label(String text)
+ {
+ this(text, LEFT);
+ }
-/**
- * Initializes a new instance of <code>Label</code> with the specified
- * text that is aligned to the left.
- *
- * @param text The text of the label.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
- */
-public
-Label(String text)
-{
- this(text, LEFT);
-}
+ /**
+ * Initializes a new instance of <code>Label</code> with the specified
+ * text and alignment.
+ *
+ * @param text The text of the label.
+ * @param alignment The desired alignment for the text in this label,
+ * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
+ * <code>RIGHT</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Label(String text, int alignment)
+ {
+ setAlignment(alignment);
+ setText(text);
-/*************************************************************************/
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException();
+ }
-/**
- * Initializes a new instance of <code>Label</code> with the specified
- * text and alignment.
- *
- * @param text The text of the label.
- * @param alignment The desired alignment for the text in this label,
- * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
- * <code>RIGHT</code>.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
- */
-public
-Label(String text, int alignment)
-{
- setAlignment (alignment);
- setText (text);
+ /**
+ * Returns the constant indicating the alignment of the text in this
+ * label. The value returned will be one of the alignment constants
+ * from this class.
+ *
+ * @return The alignment of the text in the label.
+ */
+ public int getAlignment()
+ {
+ return(alignment);
+ }
- if (GraphicsEnvironment.isHeadless())
- throw new HeadlessException ();
-}
+ /**
+ * Sets the text alignment of this label to the specified value.
+ *
+ * @param alignment The desired alignment for the text in this label,
+ * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
+ * <code>RIGHT</code>.
+ */
+ public synchronized void setAlignment(int alignment)
+ {
+ if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
+ throw new IllegalArgumentException("invalid alignment: " + alignment);
+ this.alignment = alignment;
+ if (peer != null)
+ {
+ LabelPeer lp = (LabelPeer) peer;
+ lp.setAlignment(alignment);
+ }
+ }
-/*************************************************************************/
+ /**
+ * Returns the text displayed in this label.
+ *
+ * @return The text for this label.
+ */
+ public String getText()
+ {
+ return text;
+ }
-/*
- * Instance Variables
- */
+ /**
+ * Sets the text in this label to the specified value.
+ *
+ * @param text The new text for this label.
+ */
+ public synchronized void setText(String text)
+ {
+ if ((this.text == null && text != null)
+ || (this.text != null && ! this.text.equals(text)))
+ {
+ this.text = text;
+
+ if (peer != null)
+ {
+ LabelPeer lp = (LabelPeer) peer;
+ lp.setText(text);
+ }
+ invalidate();
+ }
+ }
-/**
- * Returns the constant indicating the alignment of the text in this
- * label. The value returned will be one of the alignment constants
- * from this class.
- *
- * @return The alignment of the text in the label.
- */
-public int
-getAlignment()
-{
- return(alignment);
-}
+ /**
+ * Notifies this label that it has been added to a container, causing
+ * the peer to be created. This method is called internally by the AWT
+ * system.
+ */
+ public void addNotify()
+ {
+ if (peer == null)
+ peer = getToolkit().createLabel(this);
+ super.addNotify();
+ }
-/*************************************************************************/
+ /**
+ * Returns a parameter string useful for debugging.
+ *
+ * @return A debugging string.
+ */
+ protected String paramString()
+ {
+ return ("text=" + getText() + ",alignment=" +
+ getAlignment() + "," + super.paramString());
+ }
-/**
- * Sets the text alignment of this label to the specified value.
- *
- * @param alignment The desired alignment for the text in this label,
- * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
- * <code>RIGHT</code>.
- */
-public synchronized void
-setAlignment(int alignment)
-{
- if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
- throw new IllegalArgumentException ("invalid alignment: " + alignment);
- this.alignment = alignment;
- if (peer != null)
+ /**
+ * This class provides accessibility support for the label.
+ */
+ protected class AccessibleAWTLabel
+ extends AccessibleAWTComponent
+ {
+ /**
+ * For compatability with Sun's JDK 1.4.2 rev. 5
+ */
+ private static final long serialVersionUID = -3568967560160480438L;
+
+ /**
+ * Constructor for the accessible label.
+ */
+ public AccessibleAWTLabel()
{
- LabelPeer lp = (LabelPeer) peer;
- lp.setAlignment (alignment);
}
-}
-
-/*************************************************************************/
-
-/**
- * Returns the text displayed in this label.
- *
- * @return The text for this label.
- */
-public String
-getText()
-{
- return(text);
-}
-
-/*************************************************************************/
-/**
- * Sets the text in this label to the specified value.
- *
- * @param text The new text for this label.
- */
-public synchronized void
-setText(String text)
-{
- if ((this.text == null && text != null)
- || (this.text != null && ! this.text.equals(text)))
+ /**
+ * Returns the accessible name for the label. This is
+ * the text used in the label.
+ *
+ * @return a <code>String</code> containing the accessible
+ * name for this label.
+ */
+ public String getAccessibleName()
{
- this.text = text;
-
- if (peer != null)
- {
- LabelPeer lp = (LabelPeer) peer;
- lp.setText (text);
- }
- invalidate();
+ return getText();
}
-}
-
-/*************************************************************************/
-
-/**
- * Notifies this label that it has been added to a container, causing
- * the peer to be created. This method is called internally by the AWT
- * system.
- */
-public void
-addNotify()
-{
- if (peer == null)
- peer = getToolkit ().createLabel (this);
- super.addNotify ();
-}
-/*************************************************************************/
-
-/**
- * Returns a parameter string useful for debugging.
- *
- * @return A debugging string.
- */
-protected String
-paramString()
-{
- return ("text=" + getText() + ",alignment=" +
- getAlignment() + "," + super.paramString());
-}
+ /**
+ * Returns the accessible role for the label.
+ *
+ * @return an instance of <code>AccessibleRole</code>, describing
+ * the role of the label.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LABEL;
+ }
-/**
- * This class provides accessibility support for the label.
- */
-protected class AccessibleAWTLabel
- extends AccessibleAWTComponent
-{
- /**
- * For compatability with Sun's JDK 1.4.2 rev. 5
- */
- private static final long serialVersionUID = -3568967560160480438L;
+ }
/**
- * Constructor for the accessible label.
+ * Gets the AccessibleContext associated with this <code>Label</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
*/
- public AccessibleAWTLabel()
+ public AccessibleContext getAccessibleContext()
{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTLabel();
+ return accessibleContext;
}
/**
- * Returns the accessible name for the label. This is
- * the text used in the label.
+ * Generate a unique name for this button.
*
- * @return a <code>String</code> containing the accessible
- * name for this label.
+ * @return A unique name for this button.
*/
- public String getAccessibleName()
+ String generateName()
{
- return getText();
+ return "label" + getUniqueLong();
}
-
+
/**
- * Returns the accessible role for the label.
- *
- * @return an instance of <code>AccessibleRole</code>, describing
- * the role of the label.
+ * The number used to generate the name returned by getName.
*/
- public AccessibleRole getAccessibleRole()
+ private static transient long nextLabelNumber;
+
+ private static synchronized long getUniqueLong()
{
- return AccessibleRole.LABEL;
+ return nextLabelNumber++;
}
}
-/**
- * Gets the AccessibleContext associated with this <code>Label</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 AccessibleAWTLabel();
- return accessibleContext;
-}
-
-} // class Label
-
diff --git a/java/awt/List.java b/java/awt/List.java
index 808c4b6ed..1d703e5a6 100644
--- a/java/awt/List.java
+++ b/java/awt/List.java
@@ -161,7 +161,11 @@ List(int rows)
public
List(int rows, boolean multipleMode)
{
- this.rows = rows;
+ if (rows == 0)
+ this.rows = 4;
+ else
+ this.rows = rows;
+
this.multipleMode = multipleMode;
selected = new int[0];
@@ -645,13 +649,13 @@ clear()
* @param item The new item value.
* @param index The index of the item to replace.
*
- * @exception IllegalArgumentException If the index is not valid.
+ * @exception ArrayIndexOutOfBoundsException If the index is not valid.
*/
public synchronized void
-replaceItem(String item, int index) throws IllegalArgumentException
+replaceItem(String item, int index) throws ArrayIndexOutOfBoundsException
{
if ((index < 0) || (index >= items.size()))
- throw new IllegalArgumentException("Bad list index: " + index);
+ throw new ArrayIndexOutOfBoundsException("Bad list index: " + index);
items.insertElementAt(item, index + 1);
items.removeElementAt (index);
@@ -818,15 +822,11 @@ isSelected(int index)
/**
* This method ensures that the item at the specified index is visible.
*
- * @exception IllegalArgumentException If the specified index is out of
- * range.
+ * @param index The index of the item to be made visible.
*/
public synchronized void
makeVisible(int index) throws IllegalArgumentException
{
- if ((index < 0) || (index >= items.size()))
- throw new IllegalArgumentException("Bad list index: " + index);
-
visibleIndex = index;
if (peer != null)
{
diff --git a/java/awt/Point.java b/java/awt/Point.java
index 31b72e2cc..64bc07eaf 100644
--- a/java/awt/Point.java
+++ b/java/awt/Point.java
@@ -1,5 +1,5 @@
/* Point.java -- represents a point in 2-D space
- Copyright (C) 1999, 2002 Free Software Foundation
+ Copyright (C) 1999, 2002, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -83,7 +83,7 @@ public class Point extends Point2D implements Serializable
/**
* Initializes a new instance of <code>Point</code> representing the
- * coordiates (0,0).
+ * coordinates (0, 0).
*
* @since 1.1
*/
@@ -93,7 +93,7 @@ public class Point extends Point2D implements Serializable
/**
* Initializes a new instance of <code>Point</code> with coordinates
- * identical to the coordinates of the specified points.
+ * identical to the coordinates of the specified point.
*
* @param p the point to copy the coordinates from
* @throws NullPointerException if p is null
@@ -178,15 +178,16 @@ public class Point extends Point2D implements Serializable
/**
* Sets this object's coordinates to the specified values. This method
- * performs normal casting from double to int, so you may lose precision.
+ * rounds to the nearest integer coordinates by adding 0.5 and calling
+ * {@link Math#floor(double)}.
*
* @param x the new X coordinate
* @param y the new Y coordinate
*/
public void setLocation(double x, double y)
{
- this.x = (int) x;
- this.y = (int) y;
+ this.x = (int) Math.floor(x + 0.5);
+ this.y = (int) Math.floor(y + 0.5);
}
/**
diff --git a/java/awt/TextField.java b/java/awt/TextField.java
index ff32afa88..45be0ea51 100644
--- a/java/awt/TextField.java
+++ b/java/awt/TextField.java
@@ -96,7 +96,7 @@ private ActionListener action_listeners;
public
TextField()
{
- this("", 1);
+ this("", 0);
}
/*************************************************************************/
@@ -113,7 +113,7 @@ TextField()
public
TextField(String text)
{
- this(text, text.length());
+ this(text, (text == null) ? 0 : text.length());
}
/*************************************************************************/
@@ -147,7 +147,11 @@ public
TextField(String text, int columns)
{
super(text);
- this.columns = columns;
+
+ if (columns < 0)
+ this.columns = 0;
+ else
+ this.columns = columns;
if (GraphicsEnvironment.isHeadless())
throw new HeadlessException ();
diff --git a/java/awt/Toolkit.java b/java/awt/Toolkit.java
index 99863fab0..e2db04837 100644
--- a/java/awt/Toolkit.java
+++ b/java/awt/Toolkit.java
@@ -698,6 +698,14 @@ public abstract class Toolkit
public PrintJob getPrintJob(Frame frame, String title,
JobAttributes jobAttr, PageAttributes pageAttr)
{
+ // FIXME: it is possible this check may be removed
+ // if this method, when written, always delegates to
+ // getPrintJob(Frame, String, Properties).
+ SecurityManager sm;
+ sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPrintJobAccess();
+
return null;
}
diff --git a/java/awt/datatransfer/Clipboard.java b/java/awt/datatransfer/Clipboard.java
index 5fa1d1ab1..2029e2c35 100644
--- a/java/awt/datatransfer/Clipboard.java
+++ b/java/awt/datatransfer/Clipboard.java
@@ -1,5 +1,5 @@
/* Clipboard.java -- Class for transferring data via cut and paste.
- Copyright (C) 1999, 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -182,6 +182,9 @@ public class Clipboard
public void addFlavorListener(FlavorListener listener)
{
+ if (listener == null)
+ return;
+
synchronized(listeners)
{
listeners.add(listener);
@@ -190,6 +193,9 @@ public class Clipboard
public void removeFlavorListener(FlavorListener listener)
{
+ if (listener == null)
+ return;
+
synchronized(listeners)
{
listeners.remove(listener);
diff --git a/java/awt/datatransfer/DataFlavor.java b/java/awt/datatransfer/DataFlavor.java
index 33b98379c..63a00db13 100644
--- a/java/awt/datatransfer/DataFlavor.java
+++ b/java/awt/datatransfer/DataFlavor.java
@@ -1,5 +1,5 @@
/* DataFlavor.java -- A type of data to transfer via the clipboard.
- Copyright (C) 1999, 2001, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,6 +47,7 @@ import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Reader;
+import java.io.Serializable;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
@@ -197,31 +198,37 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
throw new ClassNotFoundException(className);
}
- private static Class getRepresentationClassFromMime(String mimeString,
+ private static Class getRepresentationClassFromMimeThrows(String mimeString,
ClassLoader classLoader)
+ throws ClassNotFoundException
{
String classname = getParameter("class", mimeString);
if (classname != null)
- {
- try
- {
- return tryToLoadClass(classname, classLoader);
- }
- catch(Exception e)
- {
- IllegalArgumentException iae;
- iae = new IllegalArgumentException("mimeString: "
- + mimeString
- + " classLoader: "
- + classLoader);
- iae.initCause(e);
- throw iae;
- }
- }
+ return tryToLoadClass(classname, classLoader);
else
return java.io.InputStream.class;
}
-
+
+ // Same as above, but wraps any ClassNotFoundExceptions
+ private static Class getRepresentationClassFromMime(String mimeString,
+ ClassLoader classLoader)
+ {
+ try
+ {
+ return getRepresentationClassFromMimeThrows(mimeString, classLoader);
+ }
+ catch(ClassNotFoundException cnfe)
+ {
+ IllegalArgumentException iae;
+ iae = new IllegalArgumentException("mimeString: "
+ + mimeString
+ + " classLoader: "
+ + classLoader);
+ iae.initCause(cnfe);
+ throw iae;
+ }
+ }
+
/**
* Returns the value of the named MIME type parameter, or <code>null</code>
* if the parameter does not exist. Given the parameter name and the mime
@@ -240,7 +247,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
String value = mimeString.substring(idx + paramName.length() + 1);
- idx = value.indexOf(" ");
+ idx = value.indexOf(";");
if (idx == -1)
return(value);
else
@@ -328,6 +335,14 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
{
this.representationClass = representationClass;
this.mimeType = mimeType;
+
+ // Do some simple validity checks
+ String type = getPrimaryType() + "/" + getSubType();
+ if (type.indexOf(' ') != -1
+ || type.indexOf('=') != -1
+ || type.indexOf(';') != -1)
+ throw new IllegalArgumentException(mimeType);
+
if (humanPresentableName != null)
this.humanPresentableName = humanPresentableName;
else
@@ -375,7 +390,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
ClassLoader classLoader)
throws ClassNotFoundException
{
- this(getRepresentationClassFromMime(mimeType, classLoader),
+ this(getRepresentationClassFromMimeThrows(mimeType, classLoader),
mimeType, humanPresentableName);
}
@@ -417,7 +432,8 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public DataFlavor(String mimeType) throws ClassNotFoundException
{
- this(mimeType, null);
+ this(getRepresentationClassFromMimeThrows(mimeType, null),
+ mimeType, null);
}
/**
@@ -567,7 +583,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isRepresentationClassInputStream()
{
- return representationClass.getName().equals("java.io.InputStream");
+ return InputStream.class.isAssignableFrom(representationClass);
}
/**
@@ -579,17 +595,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isRepresentationClassSerializable()
{
- Class[] interfaces = representationClass.getInterfaces();
-
- int i = 0;
- while (i < interfaces.length)
- {
- if (interfaces[i].getName().equals("java.io.Serializable"))
- return true;
- ++i;
- }
-
- return false;
+ return Serializable.class.isAssignableFrom(representationClass);
}
/**
@@ -634,8 +640,10 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isFlavorJavaFileListType()
{
- if (mimeType.equals(javaFileListFlavor.mimeType)
- && representationClass.equals(javaFileListFlavor.representationClass))
+ if (getPrimaryType().equals(javaFileListFlavor.getPrimaryType())
+ && getSubType().equals(javaFileListFlavor.getSubType())
+ && javaFileListFlavor.representationClass
+ .isAssignableFrom(representationClass))
return true;
return false ;
@@ -666,7 +674,11 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
/**
* This method test the specified <code>DataFlavor</code> for equality
* against this object. This will be true if the MIME type and
- * representation type are the equal.
+ * representation class are the equal. If the primary type is 'text'
+ * then also the value of the charset parameter is compared. In such a
+ * case when the charset parameter isn't given then the charset is
+ * assumed to be equal to the default charset of the platform. All
+ * other parameters are ignored.
*
* @param flavor The <code>DataFlavor</code> to test against.
*
@@ -677,12 +689,34 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
{
if (flavor == null)
return false;
-
- if (! this.mimeType.toLowerCase().equals(flavor.mimeType.toLowerCase()))
+
+ String primary = getPrimaryType();
+ if (! primary.equals(flavor.getPrimaryType()))
return false;
-
+
+ String sub = getSubType();
+ if (! sub.equals(flavor.getSubType()))
+ return false;
+
if (! this.representationClass.equals(flavor.representationClass))
return false;
+
+ if (primary.equals("text"))
+ if (! isRepresentationClassCharBuffer()
+ && ! isRepresentationClassReader()
+ && representationClass != java.lang.String.class
+ && ! (representationClass.isArray()
+ && representationClass.getComponentType() == Character.TYPE))
+ {
+ String charset = getParameter("charset");
+ String otherset = flavor.getParameter("charset");
+ String defaultset = Charset.defaultCharset().name();
+
+ if (charset == null || charset.equals(defaultset))
+ return (otherset == null || otherset.equals(defaultset));
+
+ return charset.equals(otherset);
+ }
return true;
}
diff --git a/java/awt/event/KeyEvent.java b/java/awt/event/KeyEvent.java
index d4b93ba3e..42084d733 100644
--- a/java/awt/event/KeyEvent.java
+++ b/java/awt/event/KeyEvent.java
@@ -993,6 +993,27 @@ public class KeyEvent extends InputEvent
public static final int VK_ALT_GRAPH = 65406;
/**
+ * The 'begin' key VK_BEGIN
+ *
+ * @since 1.5
+ */
+ public static final int VK_BEGIN = 65368;
+
+ /**
+ * The context-menu key VK_CONTEXT_MENU
+ *
+ * @since 1.5
+ */
+ public static final int VK_CONTEXT_MENU = 525;
+
+ /**
+ * The 'Windows' key VK_WINDOWS
+ *
+ * @since 1.5
+ */
+ public static final int VK_WINDOWS = 524;
+
+ /**
* The virtual key VK_UNDEFINED. This is used for key typed events, which
* do not have a virtual key.
*/
diff --git a/java/awt/font/FontRenderContext.java b/java/awt/font/FontRenderContext.java
index 78564a647..c50e5e509 100644
--- a/java/awt/font/FontRenderContext.java
+++ b/java/awt/font/FontRenderContext.java
@@ -83,7 +83,15 @@ public class FontRenderContext
public boolean equals (FontRenderContext rhs)
{
- return (affineTransform.equals (rhs.getTransform ())
+ if (rhs == null)
+ return false;
+
+ if (affineTransform == null && rhs.affineTransform != null
+ || affineTransform != null && rhs.affineTransform == null)
+ return false;
+
+ return ((affineTransform == rhs.affineTransform
+ || affineTransform.equals (rhs.getTransform ()))
&& isAntiAliased == rhs.isAntiAliased ()
&& usesFractionalMetrics == rhs.usesFractionalMetrics ());
}
diff --git a/java/awt/font/LineBreakMeasurer.java b/java/awt/font/LineBreakMeasurer.java
index c2a6d45d9..816c7745c 100644
--- a/java/awt/font/LineBreakMeasurer.java
+++ b/java/awt/font/LineBreakMeasurer.java
@@ -41,57 +41,41 @@ package java.awt.font;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
-import java.awt.font.TextLayout;
-import java.awt.font.FontRenderContext;
import java.awt.Shape;
public final class LineBreakMeasurer
{
private AttributedCharacterIterator text;
private int position;
- private FontRenderContext frc;
- private TextLayout totalLayout;
+ private TextMeasurer tm;
private int numChars;
public LineBreakMeasurer(AttributedCharacterIterator text,
BreakIterator breakIter, FontRenderContext frc)
{
- this.text = text;
- this.frc = frc;
- position = 0;
- totalLayout = new TextLayout(text, frc);
- numChars = totalLayout.getCharacterCount();
+ this( text, frc );
}
public LineBreakMeasurer(AttributedCharacterIterator text,
FontRenderContext frc)
{
this.text = text;
- this.frc = frc;
position = 0;
- totalLayout = new TextLayout(text, frc);
- numChars = totalLayout.getCharacterCount();
+ numChars = text.getEndIndex();
+ tm = new TextMeasurer( text, frc );
}
public void deleteChar(AttributedCharacterIterator newParagraph,
int deletePos)
{
- totalLayout = new TextLayout(newParagraph, frc);
- if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() )
- throw new NullPointerException("Invalid deletePos:"+deletePos);
- numChars = totalLayout.getCharacterCount();
- text = newParagraph;
+ tm.deleteChar( newParagraph, deletePos );
position = 0;
}
public void insertChar(AttributedCharacterIterator newParagraph,
int insertPos)
{
- totalLayout = new TextLayout(newParagraph, frc);
- if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() )
- throw new NullPointerException("Invalid insertPos:"+insertPos);
- numChars = totalLayout.getCharacterCount();
- text = newParagraph;
+ tm.insertChar( newParagraph, insertPos );
position = 0;
}
@@ -104,11 +88,9 @@ public final class LineBreakMeasurer
boolean requireNextWord)
{
int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord );
- AttributedCharacterIterator aci = (new AttributedString( text,
- position, next )
- ).getIterator();
+ TextLayout tl = tm.getLayout( position, next );
position = next;
- return new TextLayout( aci, frc );
+ return tl;
}
public int nextOffset(float wrappingWidth)
@@ -119,69 +101,40 @@ public final class LineBreakMeasurer
public int nextOffset(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
{
- Shape s = totalLayout.getBlackBoxBounds( position, offsetLimit );
- double remainingLength = s.getBounds2D().getWidth();
+ int guessOffset = tm.getLineBreakIndex(position, wrappingWidth);
+ if( offsetLimit > numChars )
+ offsetLimit = numChars;
- int guessOffset = (int)( ( (double)wrappingWidth / (double)remainingLength)
- * ( (double)numChars - (double)position ) );
- guessOffset += position;
if( guessOffset > offsetLimit )
- guessOffset = offsetLimit;
-
- s = totalLayout.getBlackBoxBounds( position, guessOffset );
- double guessLength = s.getBounds2D().getWidth();
-
- boolean makeSmaller = ( guessLength > wrappingWidth );
- int inc = makeSmaller ? -1 : 1;
- boolean keepGoing = true;
-
- do
{
- guessOffset = guessOffset + inc;
- if( guessOffset <= position || guessOffset > offsetLimit )
- {
- keepGoing = false;
- }
- else
- {
- s = totalLayout.getBlackBoxBounds( position, guessOffset );
- guessLength = s.getBounds2D().getWidth();
- if( makeSmaller && ( guessLength <= wrappingWidth) )
- keepGoing = false;
- if( !makeSmaller && ( guessLength >= wrappingWidth) )
- keepGoing = false;
- }
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
- while( keepGoing );
- if( !makeSmaller )
- guessOffset--;
+ text.setIndex( guessOffset );
- if( guessOffset >= offsetLimit )
- return offsetLimit;
+ // If we're on a breaking character, return directly
+ if( Character.isWhitespace( text.current() ) )
+ return guessOffset;
- text.setIndex( guessOffset );
+ // Otherwise jump forward or backward to the last such char.
if( !requireNextWord )
- {
- char c = text.previous();
- while( !Character.isWhitespace( c ) && c != '-' &&
- guessOffset > position )
- {
- guessOffset--;
- c = text.previous();
- }
- }
+ while( !Character.isWhitespace( text.previous() ) &&
+ guessOffset > position )
+ guessOffset--;
else
+ while( !Character.isWhitespace( text.next() ) &&
+ guessOffset < offsetLimit )
+ guessOffset++;
+
+ if( guessOffset > offsetLimit )
{
- char c = text.next();
- while( !Character.isWhitespace( c ) && c != '-' &&
- guessOffset < offsetLimit )
- {
- guessOffset++;
- c = text.next();
- }
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
+ text.setIndex( guessOffset );
+
return guessOffset;
}
diff --git a/java/awt/font/TextLayout.java b/java/awt/font/TextLayout.java
index a55aab235..9b85d7003 100644
--- a/java/awt/font/TextLayout.java
+++ b/java/awt/font/TextLayout.java
@@ -47,6 +47,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
+import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
import java.text.Bidi;
import java.util.Map;
@@ -71,6 +72,12 @@ public final class TextLayout implements Cloneable
private int[][] runIndices;
/**
+ * Character indices.
+ * Fixt index is the glyphvector, second index is the (first) glyph.
+ */
+ private int[][] charIndices;
+
+ /**
* Base directionality, determined from the first char.
*/
private boolean leftToRight;
@@ -137,6 +144,7 @@ public final class TextLayout implements Cloneable
Font.LAYOUT_LEFT_TO_RIGHT :
Font.LAYOUT_RIGHT_TO_LEFT );
}
+ setCharIndices();
}
public TextLayout (String string,
@@ -147,9 +155,97 @@ public final class TextLayout implements Cloneable
}
public TextLayout (AttributedCharacterIterator text, FontRenderContext frc)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ // FIXME: Very rudimentary.
+ this(getText(text), getFont(text), frc);
+ }
+
+ /**
+ * Package-private constructor to make a textlayout from an existing one.
+ * This is used by TextMeasurer for returning sub-layouts, and it
+ * saves a lot of time in not having to relayout the text.
+ */
+ TextLayout(TextLayout t, int startIndex, int endIndex)
+ {
+ font = t.font;
+ frc = t.frc;
+ boundsCache = null;
+ lm = t.lm;
+ leftToRight = t.leftToRight;
+
+ if( endIndex > t.getCharacterCount() )
+ endIndex = t.getCharacterCount();
+ string = t.string.substring( startIndex, endIndex );
+
+ int startingRun = t.charIndices[startIndex][0];
+ int nRuns = 1 + t.charIndices[endIndex - 1][0] - startingRun;
+ runIndices = new int[ nRuns ][2];
+
+ runs = new GlyphVector[ nRuns ];
+ for( int i = 0; i < nRuns; i++ )
+ {
+ GlyphVector run = t.runs[ i + startingRun ];
+ // Copy only the relevant parts of the first and last runs.
+ int beginGlyphIndex = (i > 0) ? 0 : t.charIndices[startIndex][1];
+ int numEntries = ( i < nRuns - 1) ? run.getNumGlyphs() :
+ 1 + t.charIndices[endIndex - 1][1] - beginGlyphIndex;
+
+ int[] codes = run.getGlyphCodes(beginGlyphIndex, numEntries, null);
+ runs[ i ] = font.createGlyphVector( frc, codes );
+ runIndices[ i ][0] = t.runIndices[i + startingRun][0] - startIndex;
+ runIndices[ i ][1] = t.runIndices[i + startingRun][1] - startIndex;
+ }
+ runIndices[ nRuns - 1 ][1] = endIndex - 1;
+
+ setCharIndices();
+ determineWhiteSpace();
+ }
+
+ private void setCharIndices()
+ {
+ charIndices = new int[ getCharacterCount() ][2];
+ int i = 0;
+ int currentChar = 0;
+ for(int run = 0; run < runs.length; run++)
+ {
+ currentChar = -1;
+ for( int gi = 0; gi < runs[ run ].getNumGlyphs(); gi++)
+ {
+ if( runs[ run ].getGlyphCharIndex( gi ) != currentChar )
+ {
+ charIndices[ i ][0] = run;
+ charIndices[ i ][1] = gi;
+ currentChar = runs[ run ].getGlyphCharIndex( gi );
+ i++;
+ }
+ }
+ }
+ }
+
+ private static String getText(AttributedCharacterIterator iter)
+ {
+ StringBuffer sb = new StringBuffer();
+ int idx = iter.getIndex();
+ for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next())
+ sb.append(c);
+ iter.setIndex( idx );
+ return sb.toString();
+ }
+
+ private static Font getFont(AttributedCharacterIterator iter)
+ {
+ Font f = (Font)iter.getAttribute(TextAttribute.FONT);
+ if( f == null )
+ {
+ int size;
+ Float i = (Float)iter.getAttribute(TextAttribute.SIZE);
+ if( i != null )
+ size = (int)i.floatValue();
+ else
+ size = 14;
+ f = new Font("Dialog", Font.PLAIN, size );
+ }
+ return f;
}
/**
@@ -179,10 +275,14 @@ public final class TextLayout implements Cloneable
gotDirection = true;
break;
}
+ determineWhiteSpace();
+ }
+ private void determineWhiteSpace()
+ {
// Determine if there's whitespace in the thing.
// Ignore trailing chars.
- i = string.length() - 1;
+ int i = string.length() - 1;
hasWhitespace = false;
while( i >= 0 && Character.isWhitespace( string.charAt(i) ) )
i--;
@@ -251,56 +351,42 @@ public final class TextLayout implements Cloneable
public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint)
{
- if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() )
+ if( secondEndpoint - firstEndpoint <= 0 )
+ return new Rectangle2D.Float(); // Hmm?
+
+ if( firstEndpoint < 0 || secondEndpoint > getCharacterCount())
return new Rectangle2D.Float();
GeneralPath gp = new GeneralPath();
- int i = 0; // run index
- double advance = 0;
-
- // go to first run
- while( runIndices[i + 1][1] < firstEndpoint )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- }
+
+ int ri = charIndices[ firstEndpoint ][0];
+ int gi = charIndices[ firstEndpoint ][1];
- int j = 0; // index into the run.
- if( runIndices[i][1] - runIndices[i][0] > 1 )
+ double advance = 0;
+
+ for( int i = 0; i < ri; i++ )
+ advance += runs[i].getLogicalBounds().getWidth();
+
+ for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
- while( runs[i].getGlyphCharIndex( j + 1 ) <
- (firstEndpoint - runIndices[i][0] ) )j++;
- }
-
- gp.append(runs[i].getGlyphVisualBounds( j ), false);
- boolean keepGoing = true;;
+ int dg;
+ if( i == charIndices[ secondEndpoint - 1 ][0] )
+ dg = charIndices[ secondEndpoint - 1][1];
+ else
+ dg = runs[i].getNumGlyphs() - 1;
- do
- {
- while( j < runs[i].getNumGlyphs() &&
- runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
- secondEndpoint )
+ for( int j = 0; j <= dg; j++ )
{
Rectangle2D r2 = (runs[i].getGlyphVisualBounds( j )).
getBounds2D();
Point2D p = runs[i].getGlyphPosition( j );
- r2.setRect( advance + p.getX(), r2.getY(),
+ r2.setRect( advance + r2.getX(), r2.getY(),
r2.getWidth(), r2.getHeight() );
gp.append(r2, false);
- j++;
}
- if( j >= runs[i].getNumGlyphs() )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- j = 0;
- }
- else
- keepGoing = false;
+ advance += runs[i].getLogicalBounds().getWidth();
}
- while( keepGoing );
-
return gp;
}
@@ -384,55 +470,42 @@ public final class TextLayout implements Cloneable
public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
Rectangle2D bounds)
{
- if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() )
+ if( secondEndpoint - firstEndpoint <= 0 )
+ return new Rectangle2D.Float(); // Hmm?
+
+ if( firstEndpoint < 0 || secondEndpoint > getCharacterCount())
return new Rectangle2D.Float();
- int i = 0; // run index
- double advance = 0;
+ Rectangle2D r = null;
+ int ri = charIndices[ firstEndpoint ][0];
+ int gi = charIndices[ firstEndpoint ][1];
- // go to first run
- if( i > 0 )
- while( runIndices[i + 1][1] < firstEndpoint )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- }
+ double advance = 0;
+
+ for( int i = 0; i < ri; i++ )
+ advance += runs[i].getLogicalBounds().getWidth();
- int j = 0; // index into the run.
- if( runIndices[i][1] - runIndices[i][0] > 1 )
+ for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
- while( runs[i].getGlyphCharIndex( j + 1 ) <
- (firstEndpoint - runIndices[i][0] ) )j++;
- }
-
- Rectangle2D r = (runs[i].getGlyphLogicalBounds( j )).getBounds2D();
- boolean keepGoing = true;;
+ int dg; // last index in this run to use.
+ if( i == charIndices[ secondEndpoint - 1 ][0] )
+ dg = charIndices[ secondEndpoint - 1][1];
+ else
+ dg = runs[i].getNumGlyphs() - 1;
- do
- {
- while( j < runs[i].getNumGlyphs() &&
- runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
- secondEndpoint )
+ for(; gi <= dg; gi++ )
{
- Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( j )).
+ Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( gi )).
getBounds2D();
- Point2D p = runs[i].getGlyphPosition( j );
- r2.setRect( advance + p.getX(), r2.getY(),
- r2.getWidth(), r2.getHeight() );
- r = r.createUnion( r2 );
- j++;
+ if( r == null )
+ r = r2;
+ else
+ r = r.createUnion(r2);
}
+ gi = 0; // reset glyph index into run for next run.
- if( j >= runs[i].getNumGlyphs() )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- j = 0;
- }
- else
- keepGoing = false;
+ advance += runs[i].getLogicalBounds().getWidth();
}
- while( keepGoing );
return r;
}
diff --git a/java/awt/font/TextMeasurer.java b/java/awt/font/TextMeasurer.java
index 18c286c57..e91c7ef16 100644
--- a/java/awt/font/TextMeasurer.java
+++ b/java/awt/font/TextMeasurer.java
@@ -1,5 +1,5 @@
/* TextMeasurer.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,67 +38,152 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.awt.Shape;
/**
- * @author Michael Koch
+ * TextMeasurer is a small utility class for measuring the length of laid-out
+ * text objects.
+ *
+ * @author Sven de Marothy
* @since 1.3
*/
public final class TextMeasurer implements Cloneable
{
- private AttributedCharacterIterator ci;
+ private AttributedCharacterIterator text;
private FontRenderContext frc;
-
+ private TextLayout totalLayout;
+ private int numChars;
+
+ /**
+ * Creates a TextMeasurer from a given text in the form of an
+ * <code>AttributedCharacterIterator</code> and a
+ * <code>FontRenderContext</code>.
+ */
public TextMeasurer (AttributedCharacterIterator text, FontRenderContext frc)
{
- this.ci = text;
+ this.text = text;
this.frc = frc;
+ totalLayout = new TextLayout( text, frc );
+ numChars = totalLayout.getCharacterCount();
}
+ /**
+ * Clones the TextMeasurer object
+ */
protected Object clone ()
{
- try
- {
- return super.clone ();
- }
- catch (CloneNotSupportedException e)
- {
- // This may never occur
- throw new InternalError ();
- }
+ return new TextMeasurer( text, frc );
}
+ /**
+ * Update the text if a character is deleted at the position deletePos
+ * @param newParagraph - the updated paragraph.
+ * @param deletePos - the deletion position
+ */
public void deleteChar (AttributedCharacterIterator newParagraph,
int deletePos)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ totalLayout = new TextLayout(newParagraph, frc);
+ if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() )
+ throw new NullPointerException("Invalid deletePos:"+deletePos);
+ numChars = totalLayout.getCharacterCount();
+ text = newParagraph;
+ }
+
+ /**
+ * Update the text if a character is inserted at the position insertPos
+ * @param newParagraph - the updated paragraph.
+ * @param insertPos - the insertion position
+ */
+ public void insertChar (AttributedCharacterIterator newParagraph,
+ int insertPos)
+ {
+ totalLayout = new TextLayout(newParagraph, frc);
+ if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() )
+ throw new NullPointerException("Invalid insertPos:"+insertPos);
+ numChars = totalLayout.getCharacterCount();
+ text = newParagraph;
}
+ /***
+ * Returns the total advance between two positions in the paragraph.
+ * Characters from start to limit-1 (inclusive) are included in this count.
+ *
+ * @param start - the starting character index.
+ * @param limit - the limiting index.
+ */
public float getAdvanceBetween (int start, int limit)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ Shape s = totalLayout.getLogicalHighlightShape( start, limit );
+ return (float)s.getBounds2D().getWidth();
}
+ /**
+ * Returns a <code>TextLayout</code> object corresponding to the characters
+ * from text to limit.
+ * @param start - the starting character index.
+ * @param limit - the limiting index.
+ */
public TextLayout getLayout (int start, int limit)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ return new TextLayout( totalLayout, start, limit );
}
+ /**
+ * Returns the line-break index from a given starting index and a maximum
+ * advance. The index returned is the first character outside the given
+ * advance (or the limit of the string, if all remaining characters fit.)
+ *
+ * @param start - the starting index.
+ * @param maxAdvance - the maximum advance allowed.
+ * @return the index of the first character beyond maxAdvance, or the
+ * index of the last character + 1.
+ */
public int getLineBreakIndex (int start, float maxAdvance)
- throws NotImplementedException
- {
- throw new Error ("not implemented");
- }
+ {
+ if( start < 0 )
+ throw new IllegalArgumentException("Start parameter must be > 0.");
+
+ double remainingLength = getAdvanceBetween( start, numChars );
+
+ int guessOffset = (int)( ( (double)maxAdvance / (double)remainingLength)
+ * ( (double)numChars - (double)start ) );
+ guessOffset += start;
+ if( guessOffset > numChars )
+ guessOffset = numChars;
+
+ double guessLength = getAdvanceBetween( start, guessOffset );
+ boolean makeSmaller = ( guessLength > maxAdvance );
+ int inc = makeSmaller ? -1 : 1;
+ boolean keepGoing = true;
+
+ do
+ {
+ guessOffset = guessOffset + inc;
+ if( guessOffset <= start || guessOffset > numChars )
+ {
+ keepGoing = false;
+ }
+ else
+ {
+ guessLength = getAdvanceBetween( start, guessOffset );
+ if( makeSmaller && ( guessLength <= maxAdvance) )
+ keepGoing = false;
+ if( !makeSmaller && ( guessLength >= maxAdvance) )
+ keepGoing = false;
+ }
+ }
+ while( keepGoing );
- public void insertChar (AttributedCharacterIterator newParagraph,
- int insertPos)
- throws NotImplementedException
- {
- throw new Error ("not implemented");
+ // Return first index that doesn't fit.
+ if( !makeSmaller )
+ guessOffset--;
+
+ if( guessOffset > numChars )
+ return numChars;
+
+ return guessOffset;
}
}
diff --git a/java/awt/image/BufferedImage.java b/java/awt/image/BufferedImage.java
index e79a09a0f..6026e7898 100644
--- a/java/awt/image/BufferedImage.java
+++ b/java/awt/image/BufferedImage.java
@@ -504,7 +504,10 @@ public class BufferedImage extends Image
int[] pixels = getRGB(x, y,
width, height,
(int[])null, offset, stride);
- ColorModel model = getColorModel();
+ // We already convert the color to RGB in the getRGB call, so
+ // we pass a simple RGB color model to the consumers.
+ ColorModel model = new DirectColorModel(32, 0xff0000, 0xff00, 0xff,
+ 0xff000000);
consumers.add(ic);
diff --git a/java/lang/Thread.java b/java/lang/Thread.java
index e039b4703..9a3e3a6f0 100644
--- a/java/lang/Thread.java
+++ b/java/lang/Thread.java
@@ -1254,4 +1254,19 @@ public class Thread implements Runnable
private static final long serialVersionUID = 605505746047245783L;
}
+
+ /**
+ * Returns the current state of the thread. This
+ * is designed for monitoring thread behaviour, rather
+ * than for synchronization control.
+ *
+ * @return the current thread state.
+ */
+ public State getState()
+ {
+ VMThread t = vmThread;
+ return t == null ? null : State.valueOf(t.getState());
+ }
+
+
}
diff --git a/java/lang/management/ClassLoadingMXBean.java b/java/lang/management/ClassLoadingMXBean.java
new file mode 100644
index 000000000..2a8651b9c
--- /dev/null
+++ b/java/lang/management/ClassLoadingMXBean.java
@@ -0,0 +1,103 @@
+/* ClassLoadingMXBean.java - Interface for a class loading bean
+ Copyright (C) 2006 Free Software Foundation
+
+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.lang.management;
+
+/**
+ * Provides access to information about the class loading
+ * behaviour of the current invocation of the virtual
+ * machine. An instance of this bean is obtained by calling
+ * {@link ManagementFactory#getClassLoadingMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public interface ClassLoadingMXBean
+{
+
+ /**
+ * Returns the number of classes currently loaded by
+ * the virtual machine.
+ *
+ * @return the number of loaded classes.
+ */
+ int getLoadedClassCount();
+
+ /**
+ * Returns the total number of classes loaded by the
+ * virtual machine since it was started. This is the
+ * sum of the currently loaded classes and those that
+ * have been unloaded.
+ *
+ * @return the total number of classes that have been
+ * loaded by the virtual machine since it started.
+ */
+ long getTotalLoadedClassCount();
+
+ /**
+ * Returns the number of classes that have been unloaded
+ * by the virtual machine since it was started.
+ *
+ * @return the number of unloaded classes.
+ */
+ long getUnloadedClassCount();
+
+ /**
+ * Returns true if the virtual machine will emit additional
+ * information when classes are loaded and unloaded. The
+ * format of the output is left up to the virtual machine.
+ *
+ * @return true if verbose class loading output is on.
+ */
+ boolean isVerbose();
+
+ /**
+ * Turns on or off the emission of additional information
+ * when classes are loaded and unloaded. The format of the
+ * output is left up to the virtual machine. This method
+ * may be called by multiple threads concurrently, but there
+ * is only one global setting of verbosity that is affected.
+ *
+ * @param verbose the new setting for verbose class loading
+ * output.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("control").
+ */
+ void setVerbose(boolean verbose);
+
+}
+
diff --git a/java/lang/management/ManagementFactory.java b/java/lang/management/ManagementFactory.java
index b3db1b96d..5f99bbe1d 100644
--- a/java/lang/management/ManagementFactory.java
+++ b/java/lang/management/ManagementFactory.java
@@ -37,6 +37,9 @@ exception statement from your version. */
package java.lang.management;
+import gnu.classpath.NotImplementedException;
+
+import gnu.java.lang.management.ClassLoadingMXBeanImpl;
import gnu.java.lang.management.OperatingSystemMXBeanImpl;
import gnu.java.lang.management.RuntimeMXBeanImpl;
@@ -71,6 +74,11 @@ public class ManagementFactory
private static RuntimeMXBean runtimeBean;
/**
+ * The class loading management bean.
+ */
+ private static ClassLoadingMXBean classLoadingBean;
+
+ /**
* Private constructor to prevent instance creation.
*/
private ManagementFactory() {}
@@ -103,4 +111,31 @@ public class ManagementFactory
return runtimeBean;
}
+ /**
+ * Returns the class loading management bean for the
+ * running virtual machine.
+ *
+ * @return an instance of {@link ClassLoadingMXBean} for
+ * this virtual machine.
+ */
+ public static ClassLoadingMXBean getClassLoadingMXBean()
+ {
+ if (classLoadingBean == null)
+ classLoadingBean = new ClassLoadingMXBeanImpl();
+ return classLoadingBean;
+ }
+
+ /**
+ * Returns the thread management bean for the running
+ * virtual machine.
+ *
+ * @return an instance of {@link ThreadMXBean} for
+ * this virtual machine.
+ */
+ public static ThreadMXBean getThreadMXBean()
+ throws NotImplementedException
+ {
+ return null;
+ }
+
}
diff --git a/java/lang/management/OperatingSystemMXBean.java b/java/lang/management/OperatingSystemMXBean.java
index 74b9ae5a1..2430a9fbf 100644
--- a/java/lang/management/OperatingSystemMXBean.java
+++ b/java/lang/management/OperatingSystemMXBean.java
@@ -39,7 +39,7 @@ package java.lang.management;
/**
* Provides access to information about the underlying operating
- * system. Instances of this bean are obtained by calling
+ * system. An instance of this bean is obtained by calling
* {@link ManagementFactory#getOperatingSystemMXBean()}.
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
diff --git a/java/lang/management/RuntimeMXBean.java b/java/lang/management/RuntimeMXBean.java
index 59b6d0eb1..a2931d127 100644
--- a/java/lang/management/RuntimeMXBean.java
+++ b/java/lang/management/RuntimeMXBean.java
@@ -42,7 +42,7 @@ import java.util.Map;
/**
* Provides access to information about the underlying virtual
- * machine. Instances of this bean are obtained by calling
+ * machine. An instance of this bean is obtained by calling
* {@link ManagementFactory#getRuntimeMXBean()}.
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
diff --git a/java/lang/management/ThreadInfo.java b/java/lang/management/ThreadInfo.java
new file mode 100644
index 000000000..53c6651ee
--- /dev/null
+++ b/java/lang/management/ThreadInfo.java
@@ -0,0 +1,405 @@
+/* ThreadInfo.java - Information on a thread
+ Copyright (C) 2006 Free Software Foundation
+
+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.lang.management;
+
+/**
+ * <p>
+ * A class which maintains information about a particular
+ * thread. This information includes:
+ * </p>
+ * <ul>
+ * <li><strong>General Thread Information:</strong>
+ * <ul>
+ * <li>The identifier of the thread.</li>
+ * <li>The name of the thread.</li>
+ * </ul>
+ * </li>
+ * <li><strong>Execution Information:</strong>
+ * <ul>
+ * <li>The current state of the thread (e.g. blocked, runnable)</li>
+ * <li>The object upon which the thread is blocked, either because
+ * the thread is waiting to obtain the monitor of that object to enter
+ * one of its synchronized monitor, or because
+ * {@link java.lang.Object#wait()} has been called while the thread
+ * was within a method of that object.</li>
+ * <li>The thread identifier of the current thread holding an object's
+ * monitor, upon which the thread described here is blocked.</li>
+ * <li>The stack trace of the thread (if requested on creation
+ * of this object</li>
+ * </ul>
+ * <li><strong>Synchronization Statistics</strong>
+ * <ul>
+ * <li>The number of times the thread has been blocked waiting for
+ * an object's monitor or in a {@link java.lang.Object#wait()} call.</li>
+ * <li>The accumulated time the thread has been blocked waiting for
+ * an object's monitor on in a {@link java.lang.Object#wait()} call.
+ * The availability of these statistics depends on the virtual machine's
+ * support for thread contention monitoring (see
+ * {@link ThreadMXBean#isThreadContentionMonitoringSupported()}.</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ * @see ThreadMXBean#isThreadContentionMonitoringSupported()
+ */
+public class ThreadInfo
+{
+
+ /**
+ * The thread which this instance concerns.
+ */
+ private Thread thread;
+
+ /**
+ * The maximum depth of the stack traces for this thread.
+ */
+ private int maxDepth;
+
+ /**
+ * Cache a local reference to the thread management bean.
+ */
+ private static ThreadMXBean bean = null;
+
+ /**
+ * Constructs a new {@link ThreadInfo} corresponding
+ * to the thread specified.
+ *
+ * @param thread the thread on which the new instance
+ * will be based.
+ */
+ ThreadInfo(Thread thread, int maxDepth)
+ {
+ this.thread = thread;
+ this.maxDepth = maxDepth;
+ }
+
+ /**
+ * Returns the number of times this thread has been
+ * in the {@link java.lang.Thread.State#BLOCKED} state.
+ * A thread enters this state when it is waiting to
+ * obtain an object's monitor. This may occur either
+ * on entering a synchronized method for the first time,
+ * or on re-entering it following a call to
+ * {@link java.lang.Object#wait()}.
+ *
+ * @return the number of times this thread has been blocked.
+ */
+ public long getBlockedCount()
+ {
+ return VMThreadInfo.getBlockedCount(thread);
+ }
+
+ /**
+ * <p>
+ * Returns the accumulated number of milliseconds this
+ * thread has been in the
+ * {@link java.lang.Thread.State#BLOCKED} state
+ * since thread contention monitoring was last enabled.
+ * A thread enters this state when it is waiting to
+ * obtain an object's monitor. This may occur either
+ * on entering a synchronized method for the first time,
+ * or on re-entering it following a call to
+ * {@link java.lang.Object#wait()}.
+ * </p>
+ * <p>
+ * Use of this method requires virtual machine support
+ * for thread contention monitoring and for this support
+ * to be enabled.
+ * </p>
+ *
+ * @return the accumulated time (in milliseconds) that this
+ * thread has spent in the blocked state, since
+ * thread contention monitoring was enabled, or -1
+ * if thread contention monitoring is disabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support contention
+ * monitoring.
+ * @see ThreadMXBean#isThreadContentionMonitoringEnabled()
+ * @see ThreadMXBean#isThreadContentionMonitoringSupported()
+ */
+ public long getBlockedTime()
+ {
+ if (bean == null)
+ bean = ManagementFactory.getThreadMXBean();
+ // Will throw UnsupportedOperationException for us
+ if (bean.isThreadContentionMonitoringEnabled())
+ return VMThreadInfo.getBlockedTime(thread);
+ else
+ return -1;
+ }
+
+ /**
+ * <p>
+ * Returns a {@link java.lang.String} representation of
+ * the monitor lock on which this thread is blocked. If
+ * the thread is not blocked, this method returns
+ * <code>null</code>.
+ * </p>
+ * <p>
+ * The returned {@link java.lang.String} is constructed
+ * using the class name and identity hashcode (usually
+ * the memory address of the object) of the lock. The
+ * two are separated by the '@' character, and the identity
+ * hashcode is represented in hexadecimal. Thus, for a
+ * lock, <code>l</code>, the returned value is
+ * the result of concatenating
+ * <code>l.getClass().getName()</code>, <code>"@"</code>
+ * and
+ * <code>Integer.toHexString(System.identityHashCode(l))</code>.
+ * The value is only unique to the extent that the identity
+ * hash code is also unique.
+ * </p>
+ *
+ * @return a string representing the lock on which this
+ * thread is blocked, or <code>null</code> if
+ * the thread is not blocked.
+ */
+ public String getLockName()
+ {
+ if (thread.getState() == Thread.State.BLOCKED)
+ return null;
+ Object lock = VMThreadInfo.getLock(thread);
+ return lock.getClass().getName() + "@" +
+ Integer.toHexString(System.identityHashCode(lock));
+ }
+
+ /**
+ * Returns the identifier of the thread which owns the
+ * monitor lock this thread is waiting for. -1 is returned
+ * if either this thread is not blocked, or the lock is
+ * not held by any other thread.
+ *
+ * @return the thread identifier of thread holding the lock
+ * this thread is waiting for, or -1 if the thread
+ * is not blocked or the lock is not held by another
+ * thread.
+ */
+ public long getLockOwnerId()
+ {
+ if (thread.getState() == Thread.State.BLOCKED)
+ return -1;
+ Thread lockOwner = VMThreadInfo.getLockOwner(thread);
+ if (lockOwner == null)
+ return -1;
+ return lockOwner.getId();
+ }
+
+ /**
+ * Returns the name of the thread which owns the
+ * monitor lock this thread is waiting for. <code>null</code>
+ * is returned if either this thread is not blocked,
+ * or the lock is not held by any other thread.
+ *
+ * @return the thread identifier of thread holding the lock
+ * this thread is waiting for, or <code>null</code>
+ * if the thread is not blocked or the lock is not
+ * held by another thread.
+ */
+ public String getLockOwnerName()
+ {
+ if (thread.getState() == Thread.State.BLOCKED)
+ return null;
+ Thread lockOwner = VMThreadInfo.getLockOwner(thread);
+ if (lockOwner == null)
+ return null;
+ return lockOwner.getName();
+ }
+
+ /**
+ * <p>
+ * Returns the stack trace of this thread to the depth
+ * specified on creation of this {@link ThreadInfo}
+ * object. If the depth is zero, an empty array will
+ * be returned. For non-zero arrays, the elements
+ * start with the most recent trace at position zero.
+ * The bottom of the stack represents the oldest method
+ * invocation which meets the depth requirements.
+ * </p>
+ * <p>
+ * Some virtual machines may not be able to return
+ * stack trace information for a thread. In these
+ * cases, an empty array will also be returned.
+ * </p>
+ *
+ * @return an array of {@link java.lang.StackTraceElement}s
+ * representing the trace of this thread.
+ */
+ public StackTraceElement[] getStackTrace()
+ {
+ if (maxDepth == 0)
+ return new StackTraceElement[0];
+ return VMThreadInfo.getStackTrace(thread, maxDepth);
+ }
+
+ /**
+ * Returns the identifier of the thread associated with
+ * this instance of {@link ThreadInfo}.
+ *
+ * @return the thread's identifier.
+ */
+ public long getThreadId()
+ {
+ return thread.getId();
+ }
+
+ /**
+ * Returns the name of the thread associated with
+ * this instance of {@link ThreadInfo}.
+ *
+ * @return the thread's name.
+ */
+ public String getThreadName()
+ {
+ return thread.getName();
+ }
+
+ /**
+ * Returns the state of the thread associated with
+ * this instance of {@link ThreadInfo}.
+ *
+ * @return the thread's state.
+ */
+ public Thread.State getThreadState()
+ {
+ return thread.getState();
+ }
+
+ /**
+ * Returns the number of times this thread has been
+ * in the {@link java.lang.Thread.State#WAITING}
+ * or {@link java.lang.Thread.State#TIMED_WAITING} state.
+ * A thread enters one of these states when it is waiting
+ * due to a call to {@link java.lang.Object.wait()},
+ * {@link java.lang.Object.join()} or
+ * {@link java.lang.concurrent.locks.LockSupport.park()},
+ * either with an infinite or timed delay, respectively.
+ *
+ * @return the number of times this thread has been waiting.
+ */
+ public long getWaitedCount()
+ {
+ return VMThreadInfo.getWaitedCount(thread);
+ }
+
+ /**
+ * <p>
+ * Returns the accumulated number of milliseconds this
+ * thread has been in the
+ * {@link java.lang.Thread.State#WAITING} or
+ * {@link java.lang.Thread.State#TIMED_WAITING} state,
+ * since thread contention monitoring was last enabled.
+ * A thread enters one of these states when it is waiting
+ * due to a call to {@link java.lang.Object.wait()},
+ * {@link java.lang.Object.join()} or
+ * {@link java.lang.concurrent.locks.LockSupport.park()},
+ * either with an infinite or timed delay, respectively.
+ * </p>
+ * <p>
+ * Use of this method requires virtual machine support
+ * for thread contention monitoring and for this support
+ * to be enabled.
+ * </p>
+ *
+ * @return the accumulated time (in milliseconds) that this
+ * thread has spent in one of the waiting states, since
+ * thread contention monitoring was enabled, or -1
+ * if thread contention monitoring is disabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support contention
+ * monitoring.
+ * @see ThreadMXBean#isThreadContentionMonitoringEnabled()
+ * @see ThreadMXBean#isThreadContentionMonitoringSupported()
+ */
+ public long getWaitedTime()
+ {
+ if (bean == null)
+ bean = ManagementFactory.getThreadMXBean();
+ // Will throw UnsupportedOperationException for us
+ if (bean.isThreadContentionMonitoringEnabled())
+ return VMThreadInfo.getWaitedTime(thread);
+ else
+ return -1;
+ }
+
+ /**
+ * Returns true if the thread is in a native method. This
+ * excludes native code which forms part of the virtual
+ * machine itself, or which results from Just-In-Time
+ * compilation.
+ *
+ * @return true if the thread is in a native method, false
+ * otherwise.
+ */
+ public boolean isInNative()
+ {
+ return VMThreadInfo.isInNative(thread);
+ }
+
+ /**
+ * Returns true if the thread has been suspended using
+ * {@link java.lang.Thread#suspend()}.
+ *
+ * @return true if the thread is suspended, false otherwise.
+ */
+ public boolean isSuspended()
+ {
+ return VMThreadInfo.isSuspended(thread);
+ }
+
+ /**
+ * Returns a {@link java.lang.String} representation of
+ * this {@link ThreadInfo} object. This takes the form
+ * <code>java.lang.ThreadInfo[id=tid, maxDepth=md]</code>,
+ * where <code>tid</code> is the thread identifier
+ * and <code>md</code> is the maximum depth used by
+ * this {@link ThreadInfo}.
+ *
+ * @return the string specified above.
+ */
+ public String toString()
+ {
+ return getClass().getName() +
+ "[id=" + thread.getId() + ", maxDepth=" +
+ maxDepth + "]";
+ }
+
+}
diff --git a/java/lang/management/ThreadMXBean.java b/java/lang/management/ThreadMXBean.java
new file mode 100644
index 000000000..2926548ad
--- /dev/null
+++ b/java/lang/management/ThreadMXBean.java
@@ -0,0 +1,497 @@
+/* ThreadMXBean.java - Interface for a thread bean
+ Copyright (C) 2006 Free Software Foundation
+
+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.lang.management;
+
+/**
+ * <p>
+ * Provides access to information about the threads
+ * of the virtual machine. An instance of this bean is
+ * obtained by calling
+ * {@link ManagementFactory#getThreadMXBean()}.
+ * </p>
+ * <p>
+ * Each thread within the virtual machine is given an
+ * identifier, which is guaranteed to be unique to a
+ * particular thread over its lifetime (after which it
+ * may be reused). The identifier for a thread may be
+ * obtained by calling {@link java.lang.Thread#getId()}.
+ * This identifier is used within implementations of this
+ * interface to obtain information about a particular thread
+ * (or series of threads, in the case of an array of identifiers).
+ * </p>
+ * <p>
+ * This bean supports some optional behaviour, which all
+ * virtual machines may not choose to implement. Specifically,
+ * this includes the monitoring of the CPU time used by a
+ * thread, and the monitoring of thread contention. The former
+ * is further subdivided into the monitoring of either just
+ * the current thread or all threads. The methods
+ * {@link #isThreadCpuTimeSupported()},
+ * {@link #isCurrentThreadCpuTimeSupported()} and
+ * {@link #isThreadContentionMonitoringSupported()} may be
+ * used to determine whether or not this functionality is
+ * supported.
+ * </p>
+ * <p>
+ * Furthermore, both these facilities may be disabled.
+ * In fact, thread contention monitoring is disabled by
+ * default, and must be explictly turned on by calling
+ * the {@link #setThreadContentionMonitoringEnabled(boolean)}
+ * method.
+ * </p>
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public interface ThreadMXBean
+{
+
+ /**
+ * <p>
+ * This method obtains a list of threads which are deadlocked
+ * waiting to obtain monitor ownership. On entering a synchronized
+ * method of an object, or re-entering it after returning from an
+ * {@link java.lang.Object#wait()} call, a thread obtains ownership
+ * of the object's monitor.
+ * </p>
+ * <p>
+ * Deadlocks can occur in this situation if one or more threads end up
+ * waiting for a monitor, P, while also retaining ownership of a monitor,
+ * Q, required by the thread that currently owns P. To give a simple
+ * example, imagine thread A calls a synchronized method, R, obtaining the
+ * monitor, P. It then sleeps within that method, allowing thread B
+ * to run, but still retaining ownership of P. B calls another
+ * synchronized method, S, which causes it to obtain the monitor, Q,
+ * of a different object. While in that method, it then wants to
+ * call the original synchronized method, R, called by A. Doing so
+ * requires ownership of P, which is still held by A. Hence, it
+ * becomes blocked.
+ * </p>
+ * <p>
+ * A then finishes its sleep, becomes runnable, and is then allowed
+ * to run, being the only eligible thread in this scenario. A tries
+ * to call the synchronized method, S. It also gets blocked, because
+ * B still holds the monitor, Q. Hence, the two threads, A and B,
+ * are deadlocked, as neither can give up its monitor without first
+ * obtaining the monitor held by the other thread.
+ * </p>
+ * <p>
+ * Calling this method in this scenario would return the thread IDs
+ * of A and B. Note that this method is not designed for controlling
+ * synchronization, but for troubleshooting problems which cause such
+ * deadlocks; it may be prohibitively expensive to use in normal
+ * operation.
+ * </p>
+ *
+ * @return an array of thread identifiers, corresponding to threads
+ * which are currently in a deadlocked situation.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("monitor").
+ */
+ long[] findMonitorDeadlockedThreads();
+
+ /**
+ * Returns all live thread identifiers at the time of initial
+ * execution. Some thread identifiers in the returned array
+ * may refer to terminated threads, if this occurs during the
+ * lifetime of this method.
+ *
+ * @return an array of thread identifiers, corresponding to
+ * current live threads.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("monitor").
+ */
+ long[] getAllThreadIds();
+
+ /**
+ * <p>
+ * Returns the total number of nanoseconds of CPU time
+ * the current thread has used. This is equivalent to calling
+ * <code>{@link #getThreadCpuTime()}(Thread.currentThread.getId())</code>.
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63. The use of this method depends on virtual machine
+ * support for measurement of the CPU time of the current thread,
+ * and on this functionality being enabled.
+ * </p>
+ *
+ * @return the total number of nanoseconds of CPU time the current
+ * thread has used, or -1 if CPU time monitoring is disabled.
+ * @throws UnsupportedOperationException if CPU time monitoring is not
+ * supported.
+ * @see #getCurrentThreadUserTime()
+ * @see #isCurrentThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeEnabled()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ long getCurrentThreadCpuTime();
+
+ /**
+ * <p>
+ * Returns the total number of nanoseconds of CPU time
+ * the current thread has executed in user mode. This is
+ * equivalent to calling
+ * <code>{@link #getThreadUserTime()}(Thread.currentThread.getId())</code>.
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63. The use of this method depends on virtual machine
+ * support for measurement of the CPU time of the current thread,
+ * and on this functionality being enabled.
+ * </p>
+ *
+ * @return the total number of nanoseconds of CPU time the current
+ * thread has executed in user mode, or -1 if CPU time
+ * monitoring is disabled.
+ * @throws UnsupportedOperationException if CPU time monitoring is not
+ * supported.
+ * @see #getCurrentThreadCpuTime()
+ * @see #isCurrentThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeEnabled()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ long getCurrentThreadUserTime();
+
+ /**
+ * Returns the number of live daemon threads.
+ *
+ * @return the number of live daemon threads.
+ */
+ int getDaemonThreadCount();
+
+ /**
+ * Returns the peak number of live threads since
+ * the virtual machine was started or the count
+ * reset using {@link #resetPeakThreadCount()}.
+ *
+ * @return the peak live thread count.
+ * @see #resetPeakThreadCount()
+ */
+ int getPeakThreadCount();
+
+ /**
+ * Returns the number of live threads, including
+ * both daemon threads and non-daemon threads.
+ *
+ * @return the current number of live threads.
+ */
+ int getThreadCount();
+
+ /**
+ * <p>
+ * Returns the total number of nanoseconds of CPU time
+ * the specified thread has used.
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63. The use of this method depends on virtual machine
+ * support for measurement of the CPU time of the current thread,
+ * and on this functionality being enabled.
+ * </p>
+ *
+ * @param id the thread identifier of the thread whose CPU time is being
+ * monitored.
+ * @return the total number of nanoseconds of CPU time the specified
+ * thread has used, or -1 if CPU time monitoring is disabled.
+ * @throws IllegalArgumentException if <code>id</code> <= 0.
+ * @throws UnsupportedOperationException if CPU time monitoring is not
+ * supported.
+ * @see #getThreadUserTime(long)
+ * @see #isThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeEnabled()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ long getThreadCpuTime(long id);
+
+ /**
+ * Returns information on the specified thread without any
+ * stack trace information. This is equivalent to
+ * <code>{@link #getThreadInfo}(id, 0)</code>. If the
+ * identifier specifies a thread which is either non-existant
+ * or not alive, then the method returns <code>null</code>.
+ *
+ * @param id the identifier of the thread to return information
+ * on.
+ * @return a {@link ThreadInfo} object pertaining to the specified
+ * thread, or <code>null</code> if the identifier specifies
+ * a thread that doesn't exist or is not alive.
+ * @throws IllegalArgumentException if <code>id</code> <= 0.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("monitor").
+ */
+ ThreadInfo getThreadInfo(long id);
+
+ /**
+ * Returns information on the specified threads without any
+ * stack trace information. This is equivalent to
+ * <code>{@link #getThreadInfo}(ids, 0)</code>. If an
+ * identifier specifies a thread which is either non-existant
+ * or not alive, then the corresponding element in the returned
+ * array is <code>null</code>.
+ *
+ * @param ids an array of thread identifiers to return information
+ * on.
+ * @return an array of {@link ThreadInfo} objects matching the
+ * specified threads. The corresponding element is
+ * <code>null</code> if the identifier specifies
+ * a thread that doesn't exist or is not alive.
+ * @throws IllegalArgumentException if an identifier in the array is
+ * <= 0.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("monitor").
+ */
+ ThreadInfo[] getThreadInfo(long[] ids);
+
+ /**
+ * Returns information on the specified thread with
+ * stack trace information to the supplied depth. If the
+ * identifier specifies a thread which is either non-existant
+ * or not alive, then the method returns <code>null</code>.
+ * A maximum depth of 0 corresponds to an empty stack trace
+ * (an empty array is returned by the appropriate
+ * {@link ThreadInfo} method). A maximum depth of
+ * <code>Integer.MAX_VALUE</code> returns the full stack trace.
+ *
+ * @param id the identifier of the thread to return information
+ * on.
+ * @param maxDepth the maximum depth of the stack trace.
+ * Values of 0 or <code>Integer.MAX_VALUE</code>
+ * correspond to an empty and full stack trace
+ * respectively.
+ * @return a {@link ThreadInfo} object pertaining to the specified
+ * thread, or <code>null</code> if the identifier specifies
+ * a thread that doesn't exist or is not alive.
+ * @throws IllegalArgumentException if <code>id</code> <= 0.
+ * @throws IllegalArgumentException if <code>maxDepth</code> <= 0.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("monitor").
+ */
+ ThreadInfo getThreadInfo(long id, int maxDepth);
+
+ /**
+ * Returns information on the specified threads with
+ * stack trace information to the supplied depth. If an
+ * identifier specifies a thread which is either non-existant
+ * or not alive, then the corresponding element in the returned
+ * array is <code>null</code>. A maximum depth of 0 corresponds
+ * to an empty stack trace (an empty array is returned by the
+ * appropriate {@link ThreadInfo} method). A maximum depth of
+ * <code>Integer.MAX_VALUE</code> returns the full stack trace.
+ *
+ * @param ids an array of thread identifiers to return information
+ * on.
+ * @param maxDepth the maximum depth of the stack trace.
+ * Values of 0 or <code>Integer.MAX_VALUE</code>
+ * correspond to an empty and full stack trace
+ * respectively.
+ * @return an array of {@link ThreadInfo} objects matching the
+ * specified threads. The corresponding element is
+ * <code>null</code> if the identifier specifies
+ * a thread that doesn't exist or is not alive.
+ * @throws IllegalArgumentException if an identifier in the array is
+ * <= 0.
+ * @throws IllegalArgumentException if <code>maxDepth</code> <= 0.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("monitor").
+ */
+ ThreadInfo[] getThreadInfo(long[] ids, int maxDepth);
+
+ /**
+ * <p>
+ * Returns the total number of nanoseconds of CPU time
+ * the specified thread has executed in user mode.
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63. The use of this method depends on virtual machine
+ * support for measurement of the CPU time of the current thread,
+ * and on this functionality being enabled.
+ * </p>
+ *
+ * @param id the thread identifier of the thread whose CPU time is being
+ * monitored.
+ * @return the total number of nanoseconds of CPU time the specified
+ * thread has executed in user mode, or -1 if CPU time monitoring
+ * is disabled.
+ * @throws IllegalArgumentException if <code>id</code> <= 0.
+ * @throws UnsupportedOperationException if CPU time monitoring is not
+ * supported.
+ * @see #getThreadCpuTime(long)
+ * @see #isThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeEnabled()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ long getThreadUserTime(long id);
+
+ /**
+ * Returns the total number of threads that have been
+ * created and started during the lifetime of the virtual
+ * machine.
+ *
+ * @return the total number of started threads.
+ */
+ long getTotalStartedThreadCount();
+
+ /**
+ * Returns true if the virtual machine supports the monitoring
+ * of the CPU time used by the current thread. This is implied
+ * by {@link isThreadCpuTimeSupported()} returning true.
+ *
+ * @return true if monitoring of the CPU time used by the current
+ * thread is supported by the virtual machine.
+ * @see #isThreadCpuTimeEnabled()
+ * @see #isThreadCpuTimeSupported()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ boolean isCurrentThreadCpuTimeSupported();
+
+ /**
+ * Returns true if thread contention monitoring is currently
+ * enabled.
+ *
+ * @return true if thread contention monitoring is enabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support contention
+ * monitoring.
+ * @see #isThreadContentionMonitoringSupported()
+ * @see #setThreadContentionMonitoringEnabled(boolean)
+ */
+ boolean isThreadContentionMonitoringEnabled();
+
+ /**
+ * Returns true if thread contention monitoring is supported
+ * by the virtual machine.
+ *
+ * @return true if thread contention monitoring is supported
+ * by the virtual machine.
+ * @see #isThreadContentionMonitoringEnabled()
+ * @see #setThreadContentionMonitoringEnabled(boolean)
+ */
+ boolean isThreadContentionMonitoringSupported();
+
+ /**
+ * Returns true if monitoring of the CPU time used by a thread
+ * is currently enabled.
+ *
+ * @return true if thread CPU time monitoring is enabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support CPU time
+ * monitoring.
+ * @see #isCurrentThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeSupported()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ boolean isThreadCpuTimeEnabled();
+
+ /**
+ * Returns true if the virtual machine supports the monitoring
+ * of the CPU time used by all threads. This implies
+ * that {@link isCurrentThreadCpuTimeSupported()} returns true.
+ *
+ * @return true if monitoring of the CPU time used by the current
+ * thread is supported by the virtual machine.
+ * @see #isCurrentThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeEnabled()
+ * @see #setThreadCpuTimeEnabled(boolean)
+ */
+ boolean isThreadCpuTimeSupported();
+
+ /**
+ * Resets the peak live thread count to the
+ * current number of live threads, as returned
+ * by {@link #getThreadCount()}.
+ *
+ * @see #getPeakThreadCount()
+ * @see #getThreadCount()
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("control").
+ */
+ void resetPeakThreadCount();
+
+ /**
+ * Toggles the monitoring of thread contention. Thread
+ * contention monitoring is disabled by default. Each
+ * time contention monitoring is re-enabled, the times
+ * it maintains are reset.
+ *
+ * @param enable true if monitoring should be enabled,
+ * false if it should be disabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support contention
+ * monitoring.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("control").
+ * @see #isThreadContentionMonitoringEnabled()
+ * @see #isThreadContentionMonitoringSupported()
+ */
+ void setThreadContentionMonitoringEnabled(boolean enable);
+
+ /**
+ * Toggles the monitoring of CPU time used by threads. The
+ * initial setting is dependent on the underlying virtual
+ * machine. On enabling CPU time monitoring, the virtual
+ * machine may take any value up to and including the current
+ * time as the start time for monitoring.
+ *
+ * @param enable true if monitoring should be enabled,
+ * false if it should be disabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support CPU time
+ * monitoring.
+ * @throws SecurityException if a security manager exists and
+ * denies ManagementPermission("control").
+ * @see #isCurrentThreadCpuTimeSupported()
+ * @see #isThreadCpuTimeEnabled()
+ * @see #isThreadCpuTimeSupported()
+ */
+ void setThreadCpuTimeEnabled(boolean enable);
+
+}
diff --git a/java/net/URL.java b/java/net/URL.java
index 967cc80f6..85037b3e7 100644
--- a/java/net/URL.java
+++ b/java/net/URL.java
@@ -482,7 +482,17 @@ public final class URL implements Serializable
}
catch (URLParseError e)
{
- throw new MalformedURLException(e.getMessage());
+ MalformedURLException mue = new MalformedURLException(e.getMessage());
+ mue.initCause(e);
+ throw mue;
+ }
+ catch (RuntimeException e)
+ {
+ // This isn't documented, but the JDK also catches
+ // RuntimeExceptions here.
+ MalformedURLException mue = new MalformedURLException(e.getMessage());
+ mue.initCause(e);
+ throw mue;
}
if (hashAt >= 0)
diff --git a/java/rmi/server/UID.java b/java/rmi/server/UID.java
index 359630422..940339e81 100644
--- a/java/rmi/server/UID.java
+++ b/java/rmi/server/UID.java
@@ -94,23 +94,23 @@ public final class UID
* The time stamp, when the UID was created.
*/
private long time;
-
+
/**
* Create the new UID that would have the described features of the
* uniqueness.
*/
public UID()
{
- time = System.currentTimeMillis();
- unique = machineId;
- if (time > last)
- {
- last = time;
- count = uidCounter = Short.MIN_VALUE;
- }
- else
+ synchronized (UID.class)
{
- synchronized (UID.class)
+ time = System.currentTimeMillis();
+ unique = machineId;
+ if (time > last)
+ {
+ last = time;
+ count = uidCounter = Short.MIN_VALUE;
+ }
+ else
{
if (uidCounter == Short.MAX_VALUE)
{
@@ -126,8 +126,7 @@ public final class UID
uidCounter = Short.MIN_VALUE;
time = last = System.currentTimeMillis();
}
-
- count = uidCounter++;
+ count = ++uidCounter;
}
}
}
@@ -210,7 +209,7 @@ public final class UID
^ hostIpHash;
}
- /**
+ /**
* Get the string representation of this UID.
*
* @return a string, uniquely identifying this id.
@@ -219,9 +218,8 @@ public final class UID
{
int max = Character.MAX_RADIX;
// Translate into object count, counting from 0.
- long lc = (count + Short.MIN_VALUE) & 0xFFFF;
- return Long.toString(time, max) + ":"
- + Long.toString(unique, max) + ":"
+ long lc = (count - Short.MIN_VALUE) & 0xFFFF;
+ return Long.toString(unique, max) + ":" + Long.toString(time, max) + "."
+ Long.toString(lc, max);
}
}
diff --git a/java/security/cert/X509CertSelector.java b/java/security/cert/X509CertSelector.java
index 205f4bcf7..154ed2e4d 100644
--- a/java/security/cert/X509CertSelector.java
+++ b/java/security/cert/X509CertSelector.java
@@ -696,7 +696,7 @@ public class X509CertSelector implements CertSelector, Cloneable
if (altNames == null)
altNames = new LinkedList();
ArrayList l = new ArrayList(2);
- l.add(new Integer(id));
+ l.add(Integer.valueOf(id));
l.add(name);
altNames.add(l);
}
@@ -715,7 +715,7 @@ public class X509CertSelector implements CertSelector, Cloneable
if (altNames == null)
altNames = new LinkedList();
ArrayList l = new ArrayList(2);
- l.add(new Integer(id));
+ l.add(Integer.valueOf(id));
l.add(name);
altNames.add(l);
}
diff --git a/java/text/AttributedString.java b/java/text/AttributedString.java
index 8528551a8..c220f6025 100644
--- a/java/text/AttributedString.java
+++ b/java/text/AttributedString.java
@@ -223,16 +223,13 @@ public class AttributedString
// If the attribute run starts before the beginning index, we
// need to junk it if it is an Annotation.
Object attrib_obj = aci.getAttribute(attrib);
- if (rs < begin)
+ rs -= begin;
+ if (rs < 0)
{
if (attrib_obj instanceof Annotation)
continue;
- rs = begin;
- }
- else
- {
- rs -= begin;
+ rs = 0;
}
// Create a map object. Yes this will only contain one attribute
@@ -245,7 +242,7 @@ public class AttributedString
c = aci.next();
}
- while(c != CharacterIterator.DONE);
+ while( aci.getIndex() < end );
attribs = new AttributeRange[accum.size()];
attribs = (AttributeRange[]) accum.toArray(attribs);
diff --git a/java/util/logging/LogManager.java b/java/util/logging/LogManager.java
index ae0f446a8..444ab6a26 100644
--- a/java/util/logging/LogManager.java
+++ b/java/util/logging/LogManager.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util.logging;
+import gnu.classpath.SystemProperties;
+
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.ByteArrayInputStream;
@@ -50,12 +52,11 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
-import gnu.classpath.SystemProperties;
-
/**
* The <code>LogManager</code> maintains a hierarchical namespace
* of Logger objects and manages properties for configuring the logging
@@ -108,11 +109,23 @@ import gnu.classpath.SystemProperties;
public class LogManager
{
/**
+ * The object name for the logging management bean.
+ * @since 1.5
+ */
+ public static final String LOGGING_MXBEAN_NAME
+ = "java.util.logging:type=Logging";
+
+ /**
* The singleton LogManager instance.
*/
private static LogManager logManager;
/**
+ * The singleton logging bean.
+ */
+ private static LoggingMXBean loggingBean;
+
+ /**
* The registered named loggers; maps the name of a Logger to
* a WeakReference to it.
*/
@@ -902,4 +915,63 @@ public class LogManager
}
}
+ /**
+ * Return the logging bean. There is a single logging bean per
+ * VM instance.
+ * @since 1.5
+ */
+ public static synchronized LoggingMXBean getLoggingMXBean()
+ {
+ if (loggingBean == null)
+ {
+ loggingBean = new LoggingMXBean()
+ {
+ public String getLoggerLevel(String logger)
+ {
+ LogManager mgr = getLogManager();
+ Logger l = mgr.getLogger(logger);
+ if (l == null)
+ return null;
+ Level lev = l.getLevel();
+ if (lev == null)
+ return "";
+ return lev.getName();
+ }
+
+ public List getLoggerNames()
+ {
+ LogManager mgr = getLogManager();
+ // This is inefficient, but perhaps better for maintenance.
+ return Collections.list(mgr.getLoggerNames());
+ }
+
+ public String getParentLoggerName(String logger)
+ {
+ LogManager mgr = getLogManager();
+ Logger l = mgr.getLogger(logger);
+ if (l == null)
+ return null;
+ l = l.getParent();
+ if (l == null)
+ return "";
+ return l.getName();
+ }
+
+ public void setLoggerLevel(String logger, String level)
+ {
+ LogManager mgr = getLogManager();
+ Logger l = mgr.getLogger(logger);
+ if (l == null)
+ throw new IllegalArgumentException("no logger named " + logger);
+ Level newLevel;
+ if (level == null)
+ newLevel = null;
+ else
+ newLevel = Level.parse(level);
+ l.setLevel(newLevel);
+ }
+ };
+ }
+ return loggingBean;
+ }
}
diff --git a/java/util/logging/LoggingMXBean.java b/java/util/logging/LoggingMXBean.java
new file mode 100644
index 000000000..5f866c980
--- /dev/null
+++ b/java/util/logging/LoggingMXBean.java
@@ -0,0 +1,85 @@
+/* LoggingMxBean.java -- Management interface for logging
+ 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.logging;
+
+import java.util.List;
+
+/**
+ * This interface represents the management interface for logging.
+ * There is a single logging bean per VM instance, which can be
+ * retrieved via {@link LogManager#getLoggingMXBean()}.
+ *
+ * @since 1.5
+ */
+public interface LoggingMXBean
+{
+ /**
+ * Return the name of the logging level given the name of
+ * a logger. Returns null if no such logger exists.
+ * @param logger the logger's name
+ * @return the logging level's name, or null
+ */
+ String getLoggerLevel(String logger);
+
+ /**
+ * Return a list of all logger names.
+ */
+ List/*<String>*/ getLoggerNames();
+
+ /**
+ * Return the name of the parent of the indicated logger.
+ * If no such logger exists, returns null. If the logger
+ * is the root logger, returns the empty string.
+ * @param logger the logger's name
+ * @return the name of the logger's parent, or null
+ */
+ String getParentLoggerName(String logger);
+
+ /**
+ * Sets the logging level for a particular logger.
+ *
+ * @param logger the name of the logger
+ * @param level the name of the new logging level, or null
+ * @throws IllegalArgumentException if the level is not
+ * recognized, or if the logger does not exist
+ * @throws SecurityException if access is denied;
+ * see {@link Logger#setLevel(Level)}
+ */
+ void setLoggerLevel(String logger, String level);
+}