diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-07-09 22:21:37 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-07-09 22:21:37 +0000 |
commit | 0a54298efa8253b9aa8680075e7d34e3688057ef (patch) | |
tree | 4b3d17942838ad751b3eecfed5c9b1b80f9a86f4 /java | |
parent | 5dcdd6c62db92f3c76da56417a0a029a27d06ec3 (diff) | |
download | classpath-0a54298efa8253b9aa8680075e7d34e3688057ef.tar.gz |
2006-07-09 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge of HEAD --> generics-branch for
2006/07/02 to 2006/07/09.
Diffstat (limited to 'java')
-rw-r--r-- | java/awt/Canvas.java | 20 | ||||
-rw-r--r-- | java/awt/Component.java | 22 | ||||
-rw-r--r-- | java/awt/Container.java | 5 | ||||
-rw-r--r-- | java/awt/LightweightDispatcher.java | 6 | ||||
-rw-r--r-- | java/awt/TextComponent.java | 2 | ||||
-rw-r--r-- | java/awt/dnd/DragGestureEvent.java | 95 | ||||
-rw-r--r-- | java/awt/dnd/DragGestureRecognizer.java | 1 | ||||
-rw-r--r-- | java/awt/dnd/DragSource.java | 106 | ||||
-rw-r--r-- | java/awt/dnd/DragSourceContext.java | 191 | ||||
-rw-r--r-- | java/awt/dnd/DropTarget.java | 55 | ||||
-rw-r--r-- | java/awt/dnd/DropTargetContext.java | 37 | ||||
-rw-r--r-- | java/awt/dnd/DropTargetDragEvent.java | 3 | ||||
-rw-r--r-- | java/awt/dnd/DropTargetDropEvent.java | 5 | ||||
-rw-r--r-- | java/awt/dnd/InvalidDnDOperationException.java | 1 | ||||
-rw-r--r-- | java/lang/management/GarbageCollectorMXBean.java | 79 | ||||
-rw-r--r-- | java/lang/management/ManagementFactory.java | 55 | ||||
-rw-r--r-- | java/lang/management/MemoryManagerMXBean.java | 77 | ||||
-rw-r--r-- | java/lang/management/MemoryPoolMXBean.java | 310 | ||||
-rw-r--r-- | java/lang/management/MemoryUsage.java | 47 | ||||
-rw-r--r-- | java/lang/management/ThreadInfo.java | 271 | ||||
-rw-r--r-- | java/util/prefs/Preferences.java | 13 |
21 files changed, 1248 insertions, 153 deletions
diff --git a/java/awt/Canvas.java b/java/awt/Canvas.java index b599582ba..2f838d60e 100644 --- a/java/awt/Canvas.java +++ b/java/awt/Canvas.java @@ -68,6 +68,11 @@ public class Canvas * Compatible with Sun's JDK. */ private static final long serialVersionUID = -2284879212465893870L; + + /** + * The number used to generate the name returned by getName. + */ + private static transient long next_canvas_number; /** * The graphics configuration associated with the canvas. @@ -343,4 +348,19 @@ public class Canvas /* Call the paint method */ paint(graphics); } + + /** + * Generate a unique name for this canvas. + * + * @return A unique name for this canvas. + */ + String generateName() + { + return "canvas" + getUniqueLong(); + } + + private static synchronized long getUniqueLong() + { + return next_canvas_number++; + } } diff --git a/java/awt/Component.java b/java/awt/Component.java index d251b2d15..c778c4921 100644 --- a/java/awt/Component.java +++ b/java/awt/Component.java @@ -746,7 +746,9 @@ public abstract class Component */ public boolean isValid() { - return valid; + // Tests show that components are invalid as long as they are not showing, even after validate() + // has been called on them. + return peer != null && valid; } /** @@ -931,7 +933,6 @@ public abstract class Component ComponentPeer currentPeer=peer; if (currentPeer != null) currentPeer.show(); - // The JDK repaints the component before invalidating the parent. // So do we. if (isShowing() && isLightweight()) @@ -1116,16 +1117,13 @@ public abstract class Component */ public void setFont(Font newFont) { - if((newFont != null && (font == null || !font.equals(newFont))) - || newFont == null) - { - Font oldFont = font; - font = newFont; - if (peer != null) - peer.setFont(font); - firePropertyChange("font", oldFont, newFont); - invalidate(); - } + Font oldFont = font; + font = newFont; + if (peer != null) + peer.setFont(font); + firePropertyChange("font", oldFont, newFont); + if (valid) + invalidate(); } /** diff --git a/java/awt/Container.java b/java/awt/Container.java index bd20b9579..daca76efb 100644 --- a/java/awt/Container.java +++ b/java/awt/Container.java @@ -342,7 +342,7 @@ public class Container extends Component if (component == null) component = new Component[4]; // FIXME, better initial size? - + // This isn't the most efficient implementation. We could do less // copying when growing the array. It probably doesn't matter. if (ncomponents >= component.length) @@ -518,7 +518,8 @@ public class Container extends Component public void setLayout(LayoutManager mgr) { layoutMgr = mgr; - invalidate(); + if (valid) + invalidate(); } /** diff --git a/java/awt/LightweightDispatcher.java b/java/awt/LightweightDispatcher.java index 7e33bd4e9..e777145b0 100644 --- a/java/awt/LightweightDispatcher.java +++ b/java/awt/LightweightDispatcher.java @@ -287,13 +287,13 @@ class LightweightDispatcher */ private Component findTarget(Container c, Point loc) { - Component[] children = c.getComponents(); + int numComponents = c.getComponentCount(); Component target = null; if (c != null) { - for (int i = 0; i < children.length; i++) + for (int i = 0; i < numComponents; i++) { - Component child = children[i]; + Component child = c.getComponent(i); if (child.isShowing()) { if (child.contains(loc.x - child.getX(), loc.y - child.getY()) diff --git a/java/awt/TextComponent.java b/java/awt/TextComponent.java index e9a10b0c5..4fc62a951 100644 --- a/java/awt/TextComponent.java +++ b/java/awt/TextComponent.java @@ -445,7 +445,7 @@ public class TextComponent extends Component this.selectionStart = selectionStart; this.selectionEnd = selectionEnd; - + TextComponentPeer tcp = (TextComponentPeer) getPeer(); if (tcp != null) tcp.select(selectionStart, selectionEnd); diff --git a/java/awt/dnd/DragGestureEvent.java b/java/awt/dnd/DragGestureEvent.java index ab03a33c8..2a22abb12 100644 --- a/java/awt/dnd/DragGestureEvent.java +++ b/java/awt/dnd/DragGestureEvent.java @@ -48,13 +48,6 @@ import java.util.EventObject; import java.util.Iterator; import java.util.List; -/** - * STUBBED - * @see DragGestureRecognizer - * @see DragGestureListener - * @see DragSource - * @since 1.2 - */ public class DragGestureEvent extends EventObject { /** @@ -66,52 +59,121 @@ public class DragGestureEvent extends EventObject private Component component; private final Point origin; private final int action; + private List<InputEvent> events; + private DragGestureRecognizer dgr; + /** + * Constructs a new DragGestureEvent. + * @param dgr - DragGestureRecognizer firing this event + * @param action - user's preferred action + * @param origin - origin of the drag + * @param events - List of events that make up the gesture + * @throws IllegalArgumentException - if input parameters are null + */ public DragGestureEvent(DragGestureRecognizer dgr, int action, Point origin, List<? extends InputEvent> events) { super(dgr); - if (origin == null || events == null) + if (origin == null || events == null || dgr == null) throw new IllegalArgumentException(); + this.origin = origin; this.action = action; + this.events = (List<InputEvent>) events; + this.dgr = dgr; + this.component = dgr.getComponent(); + this.dragSource = dgr.getDragSource(); } + /** + * Returns the source casted as a DragGestureRecognizer. + * + * @return the source casted as a DragGestureRecognizer. + */ public DragGestureRecognizer getSourceAsDragGestureRecognizer() { - return (DragGestureRecognizer) source; + return (DragGestureRecognizer) getSource(); } + + /** + * Returns the Component corresponding to this. + * + * @return the Component corresponding to this. + */ public Component getComponent() { - return null; + return component; } + + /** + * Gets the DragSource corresponding to this. + * + * @return the DragSource corresponding to this. + */ public DragSource getDragSource() { - return null; + return dragSource; } + + /** + * Returns the origin of the drag. + * + * @return the origin of the drag. + */ public Point getDragOrigin() { return origin; } + + /** + * Gets an iterator representation of the List of events. + * + * @return an iterator representation of the List of events. + */ public Iterator<InputEvent> iterator() { - return null; + return events.iterator(); } + + /** + * Gets an array representation of the List of events. + * + * @return an array representation of the List of events. + */ public Object[] toArray() { - return null; + return events.toArray(); } + + /** + * Gets an array representation of the List of events. + * + * @param array - the array to store the events in. + * @return an array representation of the List of events. + */ public Object[] toArray(Object[] array) { - return array; + return events.toArray(array); } + + /** + * Gets the user's preferred action. + * + * @return the user's preferred action. + */ public int getDragAction() { - return 0; + return action; } + + /** + * Get the event that triggered this gesture. + * + * @return the event that triggered this gesture. + */ public InputEvent getTriggerEvent() { - return null; + return dgr.getTriggerEvent(); } /** @@ -152,5 +214,6 @@ public class DragGestureEvent extends EventObject public void startDrag(Cursor dragCursor, Image dragImage, Point imageOffset, Transferable trans, DragSourceListener l) { + dragSource.startDrag(this, dragCursor, dragImage, imageOffset, trans, l); } } // class DragGestureEvent diff --git a/java/awt/dnd/DragGestureRecognizer.java b/java/awt/dnd/DragGestureRecognizer.java index 759ec9ac2..1a396f198 100644 --- a/java/awt/dnd/DragGestureRecognizer.java +++ b/java/awt/dnd/DragGestureRecognizer.java @@ -133,6 +133,7 @@ public abstract class DragGestureRecognizer implements Serializable throws NotImplementedException { events = new ArrayList(); + // FIXME: Not implemented fully. } /** diff --git a/java/awt/dnd/DragSource.java b/java/awt/dnd/DragSource.java index 014998913..90b62b5db 100644 --- a/java/awt/dnd/DragSource.java +++ b/java/awt/dnd/DragSource.java @@ -38,6 +38,8 @@ exception statement from your version. */ package java.awt.dnd; +import gnu.classpath.NotImplementedException; + import java.awt.Component; import java.awt.Cursor; import java.awt.GraphicsEnvironment; @@ -49,6 +51,7 @@ import java.awt.datatransfer.FlavorMap; import java.awt.datatransfer.SystemFlavorMap; import java.awt.datatransfer.Transferable; import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.event.MouseMotionListener; import java.io.Serializable; import java.util.EventListener; @@ -70,9 +73,10 @@ public class DragSource implements Serializable public static final Cursor DefaultLinkNoDrop = null; private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap (); - private transient DragSourceListener dragSourceListener; private transient DragSourceMotionListener dragSourceMotionListener; + + private static DragSource ds; /** * Initializes the drag source. @@ -82,19 +86,34 @@ public class DragSource implements Serializable public DragSource() { if (GraphicsEnvironment.isHeadless()) - throw new HeadlessException (); + { + ds = null; + throw new HeadlessException(); + } } /** + * Gets the default drag source. + * * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. */ public static DragSource getDefaultDragSource() { - return new DragSource(); + if (GraphicsEnvironment.isHeadless()) + { + ds = null; + throw new HeadlessException(); + } + + if (ds == null) + ds = new DragSource(); + return ds; } public static boolean isDragImageSupported() + throws NotImplementedException { + // FIXME: Implement this return false; } @@ -110,6 +129,38 @@ public class DragSource implements Serializable Transferable trans, DragSourceListener dsl, FlavorMap map) { + // http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop.html + + // This function creates a DragSourceContext object. This object tracks the + // state of the operation by listening to a native peer. In this situation, + // the DragSource may be obtained from the event or by an instance variable. + // This function also creates a new DragSourceContextPeer. + + // This function sends the same message to the context, which then forwards + // it to the peer, passing itself as a parameter. Now, the native system has + // access to the Transferable through the context. + + try + { + flavorMap = map; + DragSourceContextPeer peer = Toolkit.getDefaultToolkit(). + createDragSourceContextPeer(trigger); + DragSourceContext context = createDragSourceContext(peer, trigger, + dragCursor, + dragImage, + imageOffset, trans, + dsl); + + if (peer == null) + throw new InvalidDnDOperationException(); + + peer.startDrag(context, dragCursor, dragImage, imageOffset); + } + catch (Exception e) + { + throw new InvalidDnDOperationException("Drag and Drop system is " + + "unable to initiate a drag operation."); + } } /** @@ -156,7 +207,7 @@ public class DragSource implements Serializable /** * Creates the DragSourceContext to handle this drag. * - * @exception IllegalArgumentException FIXME + * @exception IllegalArgumentException * @exception NullPointerException If dscp, dgl, dragImage or t is null. */ protected DragSourceContext @@ -164,50 +215,31 @@ public class DragSource implements Serializable Cursor cursor, Image image, Point offset, Transferable t, DragSourceListener dsl) { - return null; + return new DragSourceContext(peer, dge, cursor, image, offset, t, dsl); } public FlavorMap getFlavorMap() { return flavorMap; } - - /** - * Dummy DragGestureRecognizer when Toolkit doesn't support drag and drop. - */ - static class NoDragGestureRecognizer extends DragGestureRecognizer - { - NoDragGestureRecognizer(DragSource ds, Component c, int actions, - DragGestureListener dgl) - { - super(ds, c, actions, dgl); - } - - protected void registerListeners() { } - protected void unregisterListeners() { } - } - + public <T extends DragGestureRecognizer> T - createDragGestureRecognizer(Class<T> recognizer, Component c, int actions, - DragGestureListener dgl) + createDragGestureRecognizer(Class<T> recognizer, + Component c, + int actions, + DragGestureListener dgl) { - DragGestureRecognizer dgr; - dgr = Toolkit.getDefaultToolkit () - .createDragGestureRecognizer (recognizer, this, c, actions, - dgl); - - if (dgr == null) - dgr = new NoDragGestureRecognizer(this, c, actions, dgl); - - return (T) dgr; + return (T) Toolkit.getDefaultToolkit().createDragGestureRecognizer(recognizer, + this, c, + actions, dgl); } - public DragGestureRecognizer - createDefaultDragGestureRecognizer(Component c, int actions, - DragGestureListener dgl) + public DragGestureRecognizer createDefaultDragGestureRecognizer(Component c, + int actions, + DragGestureListener dgl) { - return createDragGestureRecognizer (MouseDragGestureRecognizer.class, c, - actions, dgl); + return createDragGestureRecognizer(MouseDragGestureRecognizer.class, c, + actions, dgl); } /** diff --git a/java/awt/dnd/DragSourceContext.java b/java/awt/dnd/DragSourceContext.java index 88607b090..1fee5c0c3 100644 --- a/java/awt/dnd/DragSourceContext.java +++ b/java/awt/dnd/DragSourceContext.java @@ -70,8 +70,8 @@ public class DragSourceContext private Transferable transferable; private DragGestureEvent trigger; private DragSourceListener dragSourceListener; - private boolean useCustomCursor; // FIXME: currently unused but needed for serialization. - private int sourceActions; // FIXME: currently unused but needed for serialization. + private boolean useCustomCursor; + private int sourceActions; private Image image; private Point offset; @@ -82,16 +82,17 @@ public class DragSourceContext * are null, the drag action for the trigger event is DnDConstants.ACTION_NONE * or if the source actions for the DragGestureRecognizer associated with the * trigger event are equal to DnDConstants.ACTION_NONE. - * @exception NullPointerException If peer or trigger is null. + * @exception NullPointerException If peer, trans or trigger is null or if the + * image is not null but the offset is. */ public DragSourceContext (DragSourceContextPeer peer, DragGestureEvent trigger, Cursor cursor, Image image, Point offset, Transferable trans, DragSourceListener dsl) - throws NotImplementedException - { + { if (peer == null - || trigger == null) + || trigger == null || trans == null + || (image != null && offset == null)) throw new NullPointerException (); if (trigger.getComponent () == null @@ -108,37 +109,77 @@ public class DragSourceContext this.offset = offset; this.transferable = trans; this.dragSourceListener = dsl; + this.sourceActions = trigger.getSourceAsDragGestureRecognizer().getSourceActions(); - throw new Error ("not implemented"); + setCursor(cursor); + updateCurrentCursor(trigger.getDragAction(), sourceActions, DEFAULT); } + /** + * Returns the DragSource object associated with the + * DragGestureEvent. + * + * @return the DragSource associated with the trigger. + */ public DragSource getDragSource() { return trigger.getDragSource (); } + /** + * Returns the component associated with this. + * + * @return the component associated with the trigger. + */ public Component getComponent() { return trigger.getComponent (); } + /** + * Gets the trigger associated with this. + * + * @return the trigger. + */ public DragGestureEvent getTrigger() { return trigger; } + /** + * Returns the source actions for the DragGestureRecognizer. + * + * @return the source actions for DragGestureRecognizer. + */ public int getSourceActions() { - return trigger.getSourceAsDragGestureRecognizer ().getSourceActions (); + if (sourceActions == 0) + sourceActions = trigger.getSourceAsDragGestureRecognizer().getSourceActions(); + return sourceActions; } - public void setCursor (Cursor cursor) - throws NotImplementedException + /** + * Sets the cursor for this drag operation to the specified cursor. + * + * @param cursor c - the Cursor to use, or null to use the default drag + * cursor. + */ + public void setCursor(Cursor cursor) { + if (cursor == null) + useCustomCursor = false; + else + useCustomCursor = true; this.cursor = cursor; - // FIXME: Check if we need to do more here + peer.setCursor(cursor); } + /** + * Returns the current cursor or null if the default + * drag cursor is used. + * + * @return the current cursor or null. + */ public Cursor getCursor() { return cursor; @@ -165,48 +206,160 @@ public class DragSourceContext dragSourceListener = null; } + /** + * This function tells the peer that the DataFlavors have been modified. + */ public void transferablesFlavorsChanged() - throws NotImplementedException { + peer.transferablesFlavorsChanged(); } + /** + * Calls dragEnter on the listeners registered with this + * and with the DragSource. + * + * @param e - the DragSourceDragEvent + */ public void dragEnter(DragSourceDragEvent e) - throws NotImplementedException { + if (dragSourceListener != null) + dragSourceListener.dragEnter(e); + + DragSource ds = getDragSource(); + DragSourceListener[] dsl = ds.getDragSourceListeners(); + for (int i = 0; i < dsl.length; i++) + dsl[i].dragEnter(e); + + updateCurrentCursor(e.getDropAction(), e.getTargetActions(), ENTER); } + /** + * Calls dragOver on the listeners registered with this + * and with the DragSource. + * + * @param e - the DragSourceDragEvent + */ public void dragOver(DragSourceDragEvent e) - throws NotImplementedException { + if (dragSourceListener != null) + dragSourceListener.dragOver(e); + + DragSource ds = getDragSource(); + DragSourceListener[] dsl = ds.getDragSourceListeners(); + for (int i = 0; i < dsl.length; i++) + dsl[i].dragOver(e); + + updateCurrentCursor(e.getDropAction(), e.getTargetActions(), OVER); } - + + /** + * Calls dragExit on the listeners registered with this + * and with the DragSource. + * + * @param e - the DragSourceEvent + */ public void dragExit(DragSourceEvent e) - throws NotImplementedException { + if (dragSourceListener != null) + dragSourceListener.dragExit(e); + + DragSource ds = getDragSource(); + DragSourceListener[] dsl = ds.getDragSourceListeners(); + for (int i = 0; i < dsl.length; i++) + dsl[i].dragExit(e); + + updateCurrentCursor(0, 0, DEFAULT); } + /** + * Calls dropActionChanged on the listeners registered with this + * and with the DragSource. + * + * @param e - the DragSourceDragEvent + */ public void dropActionChanged(DragSourceDragEvent e) - throws NotImplementedException { + if (dragSourceListener != null) + dragSourceListener.dropActionChanged(e); + + DragSource ds = getDragSource(); + DragSourceListener[] dsl = ds.getDragSourceListeners(); + for (int i = 0; i < dsl.length; i++) + dsl[i].dropActionChanged(e); + + updateCurrentCursor(e.getDropAction(), e.getTargetActions(), CHANGED); } + /** + * Calls dragDropEnd on the listeners registered with this + * and with the DragSource. + * + * @param e - the DragSourceDropEvent + */ public void dragDropEnd(DragSourceDropEvent e) - throws NotImplementedException { + if (dragSourceListener != null) + dragSourceListener.dragDropEnd(e); + + DragSource ds = getDragSource(); + DragSourceListener[] dsl = ds.getDragSourceListeners(); + for (int i = 0; i < dsl.length; i++) + dsl[i].dragDropEnd(e); } + /** + * Calls dragMouseMoved on the listeners registered with the DragSource. + * + * @param e - the DragSourceDragEvent + */ public void dragMouseMoved(DragSourceDragEvent e) - throws NotImplementedException { + DragSource ds = getDragSource(); + DragSourceMotionListener[] dsml = ds.getDragSourceMotionListeners(); + for (int i = 0; i < dsml.length; i++) + dsml[i].dragMouseMoved(e); } + /** + * Returns the Transferable set with this object. + * + * @return the transferable. + */ public Transferable getTransferable() { return transferable; } + /** + * This function sets the drag cursor for the specified operation, actions and + * status if the default drag cursor is active. Otherwise, the cursor is not + * updated in any way. + * + * @param dropOp - the current operation. + * @param targetAct - the supported actions. + * @param status - the status of the cursor (constant). + */ protected void updateCurrentCursor(int dropOp, int targetAct, int status) throws NotImplementedException { + // FIXME: Not implemented fully + if (!useCustomCursor) + { + Cursor cursor = null; + switch (status) + { + case ENTER: + break; + case CHANGED: + break; + case OVER: + break; + default: + break; + } + + this.cursor = cursor; + peer.setCursor(cursor); + } } } // class DragSourceContext diff --git a/java/awt/dnd/DropTarget.java b/java/awt/dnd/DropTarget.java index b0d4c2ae7..2698b1dae 100644 --- a/java/awt/dnd/DropTarget.java +++ b/java/awt/dnd/DropTarget.java @@ -38,13 +38,17 @@ exception statement from your version. */ package java.awt.dnd; +import gnu.classpath.NotImplementedException; + import java.awt.Component; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Point; import java.awt.datatransfer.FlavorMap; +import java.awt.dnd.peer.DropTargetPeer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.peer.ComponentPeer; import java.io.Serializable; import java.util.EventListener; import java.util.TooManyListenersException; @@ -79,19 +83,25 @@ public class DropTarget } protected void stop () + throws NotImplementedException { + // FIXME: implement this } public void actionPerformed (ActionEvent e) + throws NotImplementedException { + // FIXME: implement this } } private Component component; private FlavorMap flavorMap; private int actions; + private DropTargetPeer peer; private DropTargetContext dropTargetContext; private DropTargetListener dropTargetListener; + private DropTarget.DropTargetAutoScroller autoscroller; private boolean active = true; /** @@ -211,33 +221,46 @@ public class DropTarget public void addDropTargetListener (DropTargetListener dtl) throws TooManyListenersException { + if (dropTargetListener != null) + throw new TooManyListenersException (); + dropTargetListener = dtl; } public void removeDropTargetListener(DropTargetListener dtl) { - // FIXME: Do we need to do something with dtl ? - dropTargetListener = null; + if (dropTargetListener != null) + dropTargetListener = null; } public void dragEnter(DropTargetDragEvent dtde) { + if (dropTargetListener != null) + dropTargetListener.dragEnter(dtde); } public void dragOver(DropTargetDragEvent dtde) { + if (dropTargetListener != null) + dropTargetListener.dragOver(dtde); } public void dropActionChanged(DropTargetDragEvent dtde) { + if (dropTargetListener != null) + dropTargetListener.dropActionChanged(dtde); } public void dragExit(DropTargetEvent dte) { + if (dropTargetListener != null) + dropTargetListener.dragExit(dte); } public void drop(DropTargetDropEvent dtde) { + if (dropTargetListener != null) + dropTargetListener.drop(dtde); } public FlavorMap getFlavorMap() @@ -250,12 +273,22 @@ public class DropTarget flavorMap = fm; } - public void addNotify(java.awt.peer.ComponentPeer peer) + public void addNotify(ComponentPeer p) { + if (p instanceof DropTargetPeer) + { + peer = (DropTargetPeer) p; + peer.addDropTarget(this); + } + else + peer = null; } - public void removeNotify(java.awt.peer.ComponentPeer peer) + public void removeNotify(ComponentPeer p) { + ((DropTargetPeer) peer).removeDropTarget(this); + peer = null; + p = null; } public DropTargetContext getDropTargetContext() @@ -268,24 +301,34 @@ public class DropTarget protected DropTargetContext createDropTargetContext() { - return new DropTargetContext (this); + if (dropTargetContext == null) + dropTargetContext = new DropTargetContext (this); + + return dropTargetContext; } protected DropTarget.DropTargetAutoScroller createDropTargetAutoScroller (Component c, Point p) { - return new DropTarget.DropTargetAutoScroller (c, p); + if (autoscroller == null) + autoscroller = new DropTarget.DropTargetAutoScroller (c, p); + + return autoscroller; } protected void initializeAutoscrolling(Point p) { + createDropTargetAutoScroller (component, p); } protected void updateAutoscroll(Point dragCursorLocn) { + if (autoscroller != null) + autoscroller.updateLocation(dragCursorLocn); } protected void clearAutoscroll() { + autoscroller = null; } } // class DropTarget diff --git a/java/awt/dnd/DropTargetContext.java b/java/awt/dnd/DropTargetContext.java index aade755da..d970e2e08 100644 --- a/java/awt/dnd/DropTargetContext.java +++ b/java/awt/dnd/DropTargetContext.java @@ -37,12 +37,11 @@ exception statement from your version. */ package java.awt.dnd; -import gnu.classpath.NotImplementedException; - import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.peer.DropTargetContextPeer; import java.io.IOException; import java.io.Serializable; import java.util.Arrays; @@ -87,7 +86,7 @@ public class DropTargetContext implements Serializable private DropTarget dropTarget; private int targetActions; - private java.awt.dnd.peer.DropTargetContextPeer dtcp; + private DropTargetContextPeer dtcp; // package private DropTargetContext(DropTarget dropTarget) @@ -105,7 +104,7 @@ public class DropTargetContext implements Serializable return dropTarget.getComponent(); } - public void addNotify(java.awt.dnd.peer.DropTargetContextPeer dtcp) + public void addNotify(DropTargetContextPeer dtcp) { this.dtcp = dtcp; } @@ -131,39 +130,39 @@ public class DropTargetContext implements Serializable * @exception InvalidDnDOperationException If a drop is not outstanding. */ public void dropComplete (boolean success) - throws NotImplementedException { - // FIXME: implement this + if (dtcp != null) + dtcp.dropComplete(success); } protected void acceptDrag (int dragOperation) - throws NotImplementedException { - // FIXME: implement this + if (dtcp != null) + dtcp.acceptDrag(dragOperation); } protected void rejectDrag () - throws NotImplementedException { - // FIXME: implement this + if (dtcp != null) + dtcp.rejectDrag(); } protected void acceptDrop (int dropOperation) - throws NotImplementedException { - // FIXME: implement this + if (dtcp != null) + dtcp.acceptDrop(dropOperation); } protected void rejectDrop () - throws NotImplementedException { - // FIXME: implement this + if (dtcp != null) + dtcp.rejectDrop(); } protected DataFlavor[] getCurrentDataFlavors () - throws NotImplementedException { - // FIXME: implement this + if (dtcp != null) + dtcp.getTransferDataFlavors(); return null; } @@ -183,9 +182,11 @@ public class DropTargetContext implements Serializable * @exception InvalidDnDOperationException If a drag is not outstanding. */ protected Transferable getTransferable() - throws InvalidDnDOperationException, NotImplementedException + throws InvalidDnDOperationException { - // FIXME: implement this + // FIXME: Implement this + if (dtcp != null) + return dtcp.getTransferable(); return null; } diff --git a/java/awt/dnd/DropTargetDragEvent.java b/java/awt/dnd/DropTargetDragEvent.java index 63d62296e..ea5b682d1 100644 --- a/java/awt/dnd/DropTargetDragEvent.java +++ b/java/awt/dnd/DropTargetDragEvent.java @@ -114,8 +114,7 @@ public class DropTargetDragEvent extends DropTargetEvent public int getDropAction() { - return 0; - //return dropAction & ((DropTargetContext) source).getTargetActions(); + return dropAction & ((DropTargetContext) source).getTargetActions(); } public Point getLocation () diff --git a/java/awt/dnd/DropTargetDropEvent.java b/java/awt/dnd/DropTargetDropEvent.java index abdc55fe5..dd85ef712 100644 --- a/java/awt/dnd/DropTargetDropEvent.java +++ b/java/awt/dnd/DropTargetDropEvent.java @@ -37,8 +37,6 @@ exception statement from your version. */ package java.awt.dnd; -import gnu.classpath.NotImplementedException; - import java.awt.Point; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; @@ -161,9 +159,8 @@ public class DropTargetDropEvent extends DropTargetEvent } public void dropComplete(boolean success) - throws NotImplementedException { - // FIXME: implement this + context.dropComplete(success); } public boolean isLocalTransfer() diff --git a/java/awt/dnd/InvalidDnDOperationException.java b/java/awt/dnd/InvalidDnDOperationException.java index 2fd9767e0..4a75610bf 100644 --- a/java/awt/dnd/InvalidDnDOperationException.java +++ b/java/awt/dnd/InvalidDnDOperationException.java @@ -59,6 +59,7 @@ public class InvalidDnDOperationException extends IllegalStateException */ public InvalidDnDOperationException() { + super(); } /** diff --git a/java/lang/management/GarbageCollectorMXBean.java b/java/lang/management/GarbageCollectorMXBean.java new file mode 100644 index 000000000..5bb0a18d3 --- /dev/null +++ b/java/lang/management/GarbageCollectorMXBean.java @@ -0,0 +1,79 @@ +/* GarbageCollectorMXBean.java - Interface for a garbage collector 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 garbage collectors + * of the virtual machine. Garbage collectors are responsible + * for removing unreferenced objects from memory. A garbage + * collector is a type of memory manager, so this interface + * is combined with that of generic memory managers. An instance + * of this bean for each garbage collector is obtained by calling + * {@link ManagementFactory#getGarbageCollectorMXBeans()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface GarbageCollectorMXBean + extends MemoryManagerMXBean +{ + + /** + * Returns the number of collections the garbage collector + * represented by this bean has made. -1 is returned if the + * collection count is undefined. + * + * @return the number of collections made, or -1 if this is + * undefined. + */ + long getCollectionCount(); + + /** + * Returns the accumulated number of milliseconds this garbage + * collector has spent freeing the memory used by unreferenced + * objects. -1 is returned if the collection time is undefined. + * Note that the accumulated time may not change, even when the + * collection count increases, if the time taken is sufficiently + * short; this depends on the resolution of the timer used. + * + * @return the accumulated number of milliseconds spent collecting, + * or -1 if this is undefined. + */ + long getCollectionTime(); + +} diff --git a/java/lang/management/ManagementFactory.java b/java/lang/management/ManagementFactory.java index 6e8010089..2de6d3b05 100644 --- a/java/lang/management/ManagementFactory.java +++ b/java/lang/management/ManagementFactory.java @@ -41,11 +41,17 @@ import gnu.classpath.SystemProperties; import gnu.java.lang.management.ClassLoadingMXBeanImpl; import gnu.java.lang.management.CompilationMXBeanImpl; +import gnu.java.lang.management.GarbageCollectorMXBeanImpl; import gnu.java.lang.management.OperatingSystemMXBeanImpl; import gnu.java.lang.management.MemoryMXBeanImpl; +import gnu.java.lang.management.MemoryManagerMXBeanImpl; +import gnu.java.lang.management.MemoryPoolMXBeanImpl; import gnu.java.lang.management.RuntimeMXBeanImpl; import gnu.java.lang.management.ThreadMXBeanImpl; +import java.util.ArrayList; +import java.util.List; + /** * <p> * Provides access to the system's management beans via a series @@ -189,4 +195,53 @@ public class ManagementFactory return compilationBean; } + /** + * Returns the memory pool beans for the running + * virtual machine. These may change during the course + * of execution. + * + * @return a list of memory pool beans, one for each pool. + */ + public static List getMemoryPoolMXBeans() + { + List poolBeans = new ArrayList(); + String[] names = VMManagementFactory.getMemoryPoolNames(); + for (int a = 0; a < names.length; ++a) + poolBeans.add(new MemoryPoolMXBeanImpl(names[a])); + return poolBeans; + } + + /** + * Returns the memory manager beans for the running + * virtual machine. These may change during the course + * of execution. + * + * @return a list of memory manager beans, one for each manager. + */ + public static List getMemoryManagerMXBeans() + { + List managerBeans = new ArrayList(); + String[] names = VMManagementFactory.getMemoryManagerNames(); + for (int a = 0; a < names.length; ++a) + managerBeans.add(new MemoryManagerMXBeanImpl(names[a])); + managerBeans.add(getGarbageCollectorMXBeans()); + return managerBeans; + } + + /** + * Returns the garbage collector beans for the running + * virtual machine. These may change during the course + * of execution. + * + * @return a list of garbage collector beans, one for each pool. + */ + public static List getGarbageCollectorMXBeans() + { + List gcBeans = new ArrayList(); + String[] names = VMManagementFactory.getGarbageCollectorNames(); + for (int a = 0; a < names.length; ++a) + gcBeans.add(new GarbageCollectorMXBeanImpl(names[a])); + return gcBeans; + } + } diff --git a/java/lang/management/MemoryManagerMXBean.java b/java/lang/management/MemoryManagerMXBean.java new file mode 100644 index 000000000..921070539 --- /dev/null +++ b/java/lang/management/MemoryManagerMXBean.java @@ -0,0 +1,77 @@ +/* MemoryManagerMXBean.java - Interface for a memory manager 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 memory managers + * of the virtual machine. An instance of this bean for each + * memory manager is obtained by calling + * {@link ManagementFactory#getMemoryManagerMXBeans()}. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MemoryManagerMXBean +{ + + /** + * Returns an array containing the names of the memory pools + * this memory manager manages. + * + * @return an array containing the name of each memory pool + * this manager is responsible for. + */ + String[] getMemoryPoolNames(); + + /** + * Returns the name of the memory manager. + * + * @return the memory manager name. + */ + String getName(); + + /** + * Returns true if this memory manager is still valid. A memory + * manager becomes invalid when it is removed by the virtual machine + * and no longer used. + * + * @return true if this memory manager is valid. + */ + boolean isValid(); + +} diff --git a/java/lang/management/MemoryPoolMXBean.java b/java/lang/management/MemoryPoolMXBean.java new file mode 100644 index 000000000..29b438c29 --- /dev/null +++ b/java/lang/management/MemoryPoolMXBean.java @@ -0,0 +1,310 @@ +/* MemoryPoolMXBean.java - Interface for a memory pool 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 one of the memory + * resources or pools used by the virtual machine. Instances + * of this bean are obtained by calling + * {@link ManagementFactory#getMemoryPoolMXBeans()}. One + * bean is returned for each memory pool provided. + * </p> + * <p> + * The memory pool bean allows the usage of the pool to be + * monitored. The bean can provide statistics on the current + * and peak usage of the pool, and on the threshold levels the + * pool uses. + * </p> + * <p> + * {@link getUsage()} returns an approximation of the current + * usage of the pool. Calls to this method are expected to be + * generally quick to perform; if the call is expensive, the + * documentation of the bean should specify so. For memory + * pool beans that represent the memory used by garbage + * collectors, the usage level includes both referenced and + * unreferenced objects. + * </p> + * <p> + * {@link getPeakUsage()} and {@link resetPeakUsage()} enable + * the retrieval of the peak usage level and setting it to the + * current usage level, respectively. Initially, the peak usage + * level is relative to the start of the virtual machine. + * </p> + * <p> + * Memory pools may also include optional support for usage thresholds. + * The usage threshold is a particular level of memory usage. When this + * value is crossed (the current memory usage becomes equal to or greater + * than this threshold level), the usage threshold count is increased. + * This feature is designed for monitoring the trend in memory usage. + * Support for a collection usage threshold is also provided, for + * particular garbage collectors. This is used to monitor the amount + * of memory left uncollected after a garbage collection cycle. There + * is no need to make special garbage collection runs to support this; + * the level following collection just needs to be monitored. + * </p> + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface MemoryPoolMXBean +{ + + /** + * Returns memory usage statistics after a best-effort attempt + * has been made to remove unused objects from the pool. This + * method is designed for use by the pools of garbage collectors, + * in order to monitor the amount of memory used after collections. + * It will return <code>null</code> if such functionality is + * unsupported by the memory pool represented by this bean. + * + * @return the memory usage of the memory pool after the most + * recent garbage collection cycle, or <code>null</code> + * if this operation is not supported. + */ + MemoryUsage getCollectionUsage(); + + /** + * Returns the collection usage threshold level in bytes. This + * value is initially zero. + * + * @return the collection usage threshold in bytes. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdExceeded() + * @see #isCollectionUsageThresholdSupported() + * @see #setCollectionUsageThreshold(long) + */ + long getCollectionUsageThreshold(); + + /** + * Returns the number of times the usage level has matched or + * exceeded the collection usage threshold. + * + * @return the number of times the usage level has matched + * or exceeded the collection usage threshold. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @see #getCollectionUsageThreshold() + * @see #isCollectionUsageThresholdExceeded() + * @see #isCollectionUsageThresholdSupported() + * @see #setCollectionUsageThreshold(long) + */ + long getCollectionUsageThresholdCount(); + + /** + * Returns the names of the memory managers associated with this + * pool. Each pool has at least one memory manager. + * + * @return an array containing the name of each memory manager + * responsible for this pool. + */ + String[] getMemoryManagerNames(); + + /** + * Returns the name of the memory pool. + * + * @return the memory pool name. + */ + String getName(); + + /** + * Returns memory usage statistics for the peak memory usage + * of the pool. The peak is the maximum memory usage occurring + * since the virtual machine was started or since the peak + * was reset by {@link #resetPeakUsage()}. The return value + * may be <code>null</code> if this pool is no longer valid. + * + * @return the memory usage of the memory pool at its peak, + * or <code>null</code> if this pool is no longer valid. + */ + MemoryUsage getPeakUsage(); + + /** + * Returns memory usage statistics for the current memory usage + * of the pool. The return value may be <code>null</code> if + * this pool is no longer valid. Obtaining these values is + * expected to be a relatively quick operation; if this will + * instead be an expensive operation to perform, the documentation + * of the implementating bean should specify that this is the + * case. The values are intended to be an estimate for monitoring + * purposes. + * + * @return the memory usage of the memory pool at present, + * or <code>null</code> if this pool is no longer valid. + */ + MemoryUsage getUsage(); + + /** + * Returns the usage threshold level in bytes. This + * value is initially defined by the virtual machine. + * + * @return the usage threshold in bytes. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @see #getUsageThresholdCount() + * @see #isUsageThresholdExceeded() + * @see #isUsageThresholdSupported() + * @see #setUsageThreshold(long) + */ + long getUsageThreshold(); + + /** + * Returns the number of times the usage level has matched or + * exceeded the usage threshold. + * + * @return the number of times the usage level has matched + * or exceeded the usage threshold. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @see #getUsageThreshold() + * @see #isUsageThresholdExceeded() + * @see #isUsageThresholdSupported() + * @see #setUsageThreshold(long) + */ + long getUsageThresholdCount(); + + /** + * Returns true if the collection usage level is equal to + * or greater than the collection usage threshold. + * + * @return true if the collection usage threshold has been + * matched or exceeded. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @see #getCollectionUsageThreshold() + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdSupported() + * @see #setCollectionUsageThreshold(long) + */ + boolean isCollectionUsageThresholdExceeded(); + + /** + * Returns true if this memory pool supports a collection usage + * level threshold. + * + * @return true if a collection usage level threshold is supported. + * @see #getCollectionUsageThreshold() + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdExceeded() + * @see #setCollectionUsageThreshold(long) + */ + boolean isCollectionUsageThresholdSupported(); + + /** + * Returns true if the usage level is equal to + * or greater than the usage threshold. + * + * @return true if the usage threshold has been + * matched or exceeded. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @see #getUsageThreshold() + * @see #getUsageThresholdCount() + * @see #isUsageThresholdSupported() + * @see #setUsageThreshold(long) + */ + boolean isUsageThresholdExceeded(); + + /** + * Returns true if this memory pool supports a usage level threshold. + * + * @return true if a usage level threshold is supported. + * @see #getUsageThreshold() + * @see #getUsageThresholdCount() + * @see #isUsageThresholdExceeded() + * @see #setUsageThreshold(long) + */ + boolean isUsageThresholdSupported(); + + /** + * Returns true if this memory pool is still valid. A memory pool + * becomes invalid when it is removed by the virtual machine and + * no longer used. + * + * @return true if this memory pool is valid. + */ + boolean isValid(); + + /** + * Resets the peak memory usage level to the current memory usage + * level. + * + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + */ + void resetPeakUsage(); + + /** + * Sets the collection threshold usage level to the given value. + * A value of zero disables the collection threshold. + * + * @param threshold the new threshold level. + * @throws IllegalArgumentException if the threshold hold level + * is negative. + * @throws UnsupportedOperationException if the collection usage + * threshold is not supported. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + * @see #getCollectionUsageThreshold() + * @see #getCollectionUsageThresholdCount() + * @see #isCollectionUsageThresholdExceeded() + * @see #isCollectionUsageThresholdSupported() + */ + void setCollectionUsageThreshold(long threshold); + + /** + * Sets the threshold usage level to the given value. A value of + * zero disables the threshold. + * + * @param threshold the new threshold level. + * @throws IllegalArgumentException if the threshold hold level + * is negative. + * @throws UnsupportedOperationException if the usage threshold + * is not supported. + * @throws SecurityException if a security manager exists and + * denies ManagementPermission("control"). + * @see #getUsageThreshold() + * @see #getUsageThresholdCount() + * @see #isUsageThresholdExceeded() + * @see #isUsageThresholdSupported() + */ + void setUsageThreshold(long threshold); + +} diff --git a/java/lang/management/MemoryUsage.java b/java/lang/management/MemoryUsage.java index 667689507..3c2a4cba6 100644 --- a/java/lang/management/MemoryUsage.java +++ b/java/lang/management/MemoryUsage.java @@ -37,6 +37,9 @@ exception statement from your version. */ package java.lang.management; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.SimpleType; /** * <p> * Retains information on the usage of a particular memory @@ -146,6 +149,48 @@ public class MemoryUsage } /** + * <p> + * Returns a {@link MemoryUsage} instance using the values + * given in the supplied + * {@link javax.management.openmbean.CompositeData} object. + * The composite data instance should contain the following + * attributes: + * </p> + * <ul> + * <li>init</li> + * <li>used</li> + * <li>committed</li> + * <li>max</li> + * </ul> + * <p> + * All should have the type, <code>java.lang.Long</code>. + * </p> + * + * @param data the composite data structure to take values from. + * @return a new instance containing the values from the + * composite data structure, or <code>null</code> + * if the data structure was also <code>null</code>. + * @throws IllegalArgumentException if the composite data structure + * does not match the structure + * outlined above, or the values + * are invalid. + */ + public static MemoryUsage from(CompositeData data) + { + if (data == null) + return null; + CompositeType type = data.getCompositeType(); + ThreadInfo.checkAttribute(type, "init", SimpleType.LONG); + ThreadInfo.checkAttribute(type, "used", SimpleType.LONG); + ThreadInfo.checkAttribute(type, "committed", SimpleType.LONG); + ThreadInfo.checkAttribute(type, "max", SimpleType.LONG); + return new MemoryUsage(((Long) data.get("init")).longValue(), + ((Long) data.get("used")).longValue(), + ((Long) data.get("committed")).longValue(), + ((Long) data.get("max")).longValue()); + } + + /** * Returns the amount of memory committed for use by this * memory pool (in bytes). This amount is guaranteed to * be available, unlike the maximum. @@ -213,7 +258,7 @@ public class MemoryUsage "MB), used=" + used + " bytes (~" + (used / megabyte) + "MB), committed=" + committed + " bytes (~" + (committed / megabyte) + "MB), maximum=" + maximum + " bytes (~" + (maximum / megabyte) + - "]"; + "MB)]"; } } diff --git a/java/lang/management/ThreadInfo.java b/java/lang/management/ThreadInfo.java index 28a038099..44aff6f1f 100644 --- a/java/lang/management/ThreadInfo.java +++ b/java/lang/management/ThreadInfo.java @@ -37,6 +37,13 @@ exception statement from your version. */ package java.lang.management; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; + /** * <p> * A class which maintains information about a particular @@ -83,9 +90,19 @@ public class ThreadInfo { /** - * The thread which this instance concerns. + * The id of the thread which this instance concerns. + */ + private long threadId; + + /** + * The name of the thread which this instance concerns. + */ + private String threadName; + + /** + * The state of the thread which this instance concerns. */ - private Thread thread; + private Thread.State threadState; /** * The number of times the thread has been blocked. @@ -100,17 +117,24 @@ public class ThreadInfo private long blockedTime; /** - * The monitor lock on which this thread is blocked - * (if any). + * The name of the monitor lock on which this thread + * is blocked (if any). */ - private Object lock; + private String lockName; /** - * The thread which owns the monitor lock on which this - * thread is blocked, or <code>null</code> if there is - * no owner. + * The id of the thread which owns the monitor lock on + * which this thread is blocked, or <code>-1</code> + * if there is no owner. */ - private Thread lockOwner; + private long lockOwnerId; + + /** + * The name of the thread which owns the monitor lock on + * which this thread is blocked, or <code>null</code> + * if there is no owner. + */ + private String lockOwnerName; /** * The number of times the thread has been in a waiting @@ -176,11 +200,60 @@ public class ThreadInfo long waitedTime, boolean isInNative, boolean isSuspended, StackTraceElement[] trace) { - this.thread = thread; + this(thread.getId(), thread.getName(), thread.getState(), blockedCount, + blockedTime, lock.getClass().getName() + "@" + + Integer.toHexString(System.identityHashCode(lock)), lockOwner.getId(), + lockOwner.getName(), waitedCount, waitedTime, isInNative, isSuspended, + trace); + } + + /** + * Constructs a new {@link ThreadInfo} corresponding + * to the thread details specified. + * + * @param threadId the id of the thread on which this + * new instance will be based. + * @param threadName the name of the thread on which + * this new instance will be based. + * @param threadState the state of the thread on which + * this new instance will be based. + * @param blockedCount the number of times the thread + * has been blocked. + * @param blockedTime the accumulated number of milliseconds + * the specified thread has been blocked + * (only used with contention monitoring enabled) + * @param lockName the name of the monitor lock the thread is waiting for + * (only used if blocked) + * @param lockOwnerId the id of the thread which owns the monitor + * lock, or <code>-1</code> if it doesn't have an owner + * (only used if blocked) + * @param lockOwnerName the name of the thread which owns the monitor + * lock, or <code>null</code> if it doesn't have an + * owner (only used if blocked) + * @param waitedCount the number of times the thread has been in a + * waiting state. + * @param waitedTime the accumulated number of milliseconds the + * specified thread has been waiting + * (only used with contention monitoring enabled) + * @param isInNative true if the thread is in a native method. + * @param isSuspended true if the thread is suspended. + * @param trace the stack trace of the thread to a pre-determined + * depth (see VMThreadMXBeanImpl) + */ + private ThreadInfo(long threadId, String threadName, Thread.State threadState, + long blockedCount, long blockedTime, String lockName, + long lockOwnerId, String lockOwnerName, long waitedCount, + long waitedTime, boolean isInNative, boolean isSuspended, + StackTraceElement[] trace) + { + this.threadId = threadId; + this.threadName = threadName; + this.threadState = threadState; this.blockedCount = blockedCount; this.blockedTime = blockedTime; - this.lock = lock; - this.lockOwner = lockOwner; + this.lockName = lockName; + this.lockOwnerId = lockOwnerId; + this.lockOwnerName = lockOwnerName; this.waitedCount = waitedCount; this.waitedTime = waitedTime; this.isInNative = isInNative; @@ -189,6 +262,145 @@ public class ThreadInfo } /** + * Checks for an attribute in a {@link CompositeData} structure + * with the correct type. + * + * @param ctype the composite data type to check. + * @param name the name of the attribute. + * @param type the type to check for. + * @throws IllegalArgumentException if the attribute is absent + * or of the wrong type. + */ + static void checkAttribute(CompositeType ctype, String name, + OpenType type) + throws IllegalArgumentException + { + OpenType foundType = ctype.getType(name); + if (foundType == null) + throw new IllegalArgumentException("Could not find a field named " + + name); + if (!(foundType.equals(type))) + throw new IllegalArgumentException("Field " + name + " is not of " + + "type " + type.getClassName()); + } + + /** + * <p> + * Returns a {@link ThreadInfo} instance using the values + * given in the supplied + * {@link javax.management.openmbean.CompositeData} object. + * The composite data instance should contain the following + * attributes with the specified types: + * </p> + * <table> + * <th><td>Name</td><td>Type</td></th> + * <tr><td>threadId</td><td>java.lang.Long</td></tr> + * <tr><td>threadName</td><td>java.lang.String</td></tr> + * <tr><td>threadState</td><td>java.lang.String</td></tr> + * <tr><td>suspended</td><td>java.lang.Boolean</td></tr> + * <tr><td>inNative</td><td>java.lang.Boolean</td></tr> + * <tr><td>blockedCount</td><td>java.lang.Long</td></tr> + * <tr><td>blockedTime</td><td>java.lang.Long</td></tr> + * <tr><td>waitedCount</td><td>java.lang.Long</td></tr> + * <tr><td>waitedTime</td><td>java.lang.Long</td></tr> + * <tr><td>lockName</td><td>java.lang.String</td></tr> + * <tr><td>lockOwnerId</td><td>java.lang.Long</td></tr> + * <tr><td>lockOwnerName</td><td>java.lang.String</td></tr> + * <tr><td>stackTrace</td><td>javax.management.openmbean.CompositeData[] + * </td></tr> + * </table> + * <p> + * The stack trace is further described as: + * </p> + * <table> + * <th><td>Name</td><td>Type</td></th> + * <tr><td>className</td><td>java.lang.String</td></tr> + * <tr><td>methodName</td><td>java.lang.String</td></tr> + * <tr><td>fileName</td><td>java.lang.String</td></tr> + * <tr><td>lineNumber</td><td>java.lang.Integer</td></tr> + * <tr><td>nativeMethod</td><td>java.lang.Boolean</td></tr> + * </table> + * + * @param data the composite data structure to take values from. + * @return a new instance containing the values from the + * composite data structure, or <code>null</code> + * if the data structure was also <code>null</code>. + * @throws IllegalArgumentException if the composite data structure + * does not match the structure + * outlined above. + */ + public static ThreadInfo from(CompositeData data) + { + if (data == null) + return null; + CompositeType type = data.getCompositeType(); + checkAttribute(type, "threadId", SimpleType.LONG); + checkAttribute(type, "threadName", SimpleType.STRING); + checkAttribute(type, "threadState", SimpleType.STRING); + checkAttribute(type, "suspended", SimpleType.BOOLEAN); + checkAttribute(type, "inNative", SimpleType.BOOLEAN); + checkAttribute(type, "blockedCount", SimpleType.LONG); + checkAttribute(type, "blockedTime", SimpleType.LONG); + checkAttribute(type, "waitedCount", SimpleType.LONG); + checkAttribute(type, "waitedTime", SimpleType.LONG); + checkAttribute(type, "lockName", SimpleType.STRING); + checkAttribute(type, "lockOwnerId", SimpleType.LONG); + checkAttribute(type, "lockOwnerName", SimpleType.STRING); + try + { + CompositeType seType = + new CompositeType(StackTraceElement.class.getName(), + "An element of a stack trace", + new String[] { "className", "methodName", + "fileName", "lineNumber", + "nativeMethod" + }, + new String[] { "Name of the class", + "Name of the method", + "Name of the source code file", + "Line number", + "True if this is a native method" + }, + new OpenType[] { + SimpleType.STRING, SimpleType.STRING, + SimpleType.STRING, SimpleType.INTEGER, + SimpleType.BOOLEAN + }); + checkAttribute(type, "stackTrace", new ArrayType(1, seType)); + } + catch (OpenDataException e) + { + throw new IllegalStateException("Something went wrong in creating " + + "the composite data type for the " + + "stack trace element.", e); + } + CompositeData[] dTraces = (CompositeData[]) data.get("stackTrace"); + StackTraceElement[] traces = new StackTraceElement[dTraces.length]; + for (int a = 0; a < dTraces.length; ++a) + /* FIXME: We can't use the boolean as there is no available + constructor. */ + traces[a] = + new StackTraceElement((String) dTraces[a].get("className"), + (String) dTraces[a].get("methodName"), + (String) dTraces[a].get("fileName"), + ((Integer) + dTraces[a].get("lineNumber")).intValue()); + return new ThreadInfo(((Long) data.get("threadId")).longValue(), + (String) data.get("threadName"), + Thread.State.valueOf((String) data.get("threadState")), + ((Long) data.get("blockedCount")).longValue(), + ((Long) data.get("blockedTime")).longValue(), + (String) data.get("lockName"), + ((Long) data.get("lockOwnerId")).longValue(), + (String) data.get("lockOwnerName"), + ((Long) data.get("waitedCount")).longValue(), + ((Long) data.get("waitedTime")).longValue(), + ((Boolean) data.get("inNative")).booleanValue(), + ((Boolean) data.get("suspended")).booleanValue(), + traces); + } + + /** * 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 @@ -272,10 +484,9 @@ public class ThreadInfo */ public String getLockName() { - if (thread.getState() == Thread.State.BLOCKED) + if (threadState != Thread.State.BLOCKED) return null; - return lock.getClass().getName() + "@" + - Integer.toHexString(System.identityHashCode(lock)); + return lockName; } /** @@ -291,11 +502,9 @@ public class ThreadInfo */ public long getLockOwnerId() { - if (thread.getState() == Thread.State.BLOCKED) - return -1; - if (lockOwner == null) + if (threadState != Thread.State.BLOCKED) return -1; - return lockOwner.getId(); + return lockOwnerId; } /** @@ -311,11 +520,9 @@ public class ThreadInfo */ public String getLockOwnerName() { - if (thread.getState() == Thread.State.BLOCKED) - return null; - if (lockOwner == null) + if (threadState != Thread.State.BLOCKED) return null; - return lockOwner.getName(); + return lockOwnerName; } /** @@ -350,7 +557,7 @@ public class ThreadInfo */ public long getThreadId() { - return thread.getId(); + return threadId; } /** @@ -361,7 +568,7 @@ public class ThreadInfo */ public String getThreadName() { - return thread.getName(); + return threadName; } /** @@ -372,7 +579,7 @@ public class ThreadInfo */ public Thread.State getThreadState() { - return thread.getState(); + return threadState; } /** @@ -480,17 +687,17 @@ public class ThreadInfo */ public String toString() { - Thread.State state = thread.getState(); return getClass().getName() + - "[id=" + thread.getId() + - ", name=" + thread.getName() + - ", state=" + state + + "[id=" + threadId + + ", name=" + threadName + + ", state=" + threadState + ", blockedCount=" + blockedCount + ", waitedCount=" + waitedCount + ", isInNative=" + isInNative + ", isSuspended=" + isSuspended + - ((state == Thread.State.BLOCKED) ? ", lock=" + lock + - ", lockOwner=" + lockOwner : "") + + (threadState == Thread.State.BLOCKED ? + ", lockOwnerId=" + lockOwnerId + + ", lockOwnerName=" + lockOwnerName : "") + "]"; } diff --git a/java/util/prefs/Preferences.java b/java/util/prefs/Preferences.java index dfcc27b2b..e53e4fc79 100644 --- a/java/util/prefs/Preferences.java +++ b/java/util/prefs/Preferences.java @@ -37,6 +37,7 @@ exception statement from your version. */ package java.util.prefs; +import gnu.classpath.ServiceFactory; import gnu.java.util.prefs.NodeReader; import java.io.IOException; @@ -45,6 +46,7 @@ import java.io.OutputStream; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; +import java.util.Iterator; /** * Preference node containing key value entries and subnodes. @@ -205,6 +207,17 @@ public abstract class Preferences { } }); + // Still no factory? Try to see if we have one defined + // as a System Preference + if (factory == null) + { + Iterator iter = ServiceFactory.lookupProviders + (PreferencesFactory.class, null); + + if (iter != null && iter.hasNext()) + factory = (PreferencesFactory) iter.next(); + } + // Still no factory? Use our default. if (factory == null) { |