From c90d91d5fcb4ba793d5a4f1cacda1cfe8f74aaf4 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Fri, 17 Sep 2010 13:23:33 -0400 Subject: [PATCH 01/88] 6983452: SyncProvider issue for JoinRowSet implementation Reviewed-by: darcy, ohair --- jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java index cc3ebbfc21b..1c8f279a4ad 100644 --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -889,7 +889,12 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern success = false; } else { tWriter = (TransactionalWriter)rowSetWriter; - ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + if (tWriter instanceof CachedRowSetWriter) { + ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + } else { + tWriter.commit(); + } + success = true; } } From 45ad71b5655002212b1b1bd5b954e4761829c1fe Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Fri, 17 Sep 2010 13:26:17 -0400 Subject: [PATCH 02/88] 6984864: Exception when running acceptChanges with custom SyncProvider Reviewed-by: darcy, ohair --- .../com/sun/rowset/JoinRowSetImpl.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java index 6963d5748f8..a1380586809 100644 --- a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java @@ -33,6 +33,8 @@ import java.math.*; import java.util.*; import javax.sql.rowset.*; +import javax.sql.rowset.spi.SyncProvider; +import javax.sql.rowset.spi.SyncProviderException; /** * The standard implementation of the JoinRowSet @@ -4311,6 +4313,27 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { return crsInternal.createCopySchema(); } + /** + * {@inheritDoc} + */ + public void setSyncProvider(String providerStr) throws SQLException { + crsInternal.setSyncProvider(providerStr); + } + + /** + * {@inheritDoc} + */ + public void acceptChanges() throws SyncProviderException { + crsInternal.acceptChanges(); + } + + /** + * {@inheritDoc} + */ + public SyncProvider getSyncProvider() throws SQLException { + return crsInternal.getSyncProvider(); + } + /** * This method re populates the resBundle * during the deserialization process From 979b63326fec17695ead6021799e56ce3156597a Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Fri, 17 Sep 2010 13:30:44 -0400 Subject: [PATCH 03/88] 6985400: DatabaseMetaData.generatedKeyAlwaysReturned, "indexe(s)" should be "index(es)" Reviewed-by: darcy, ohair --- jdk/src/share/classes/java/sql/DatabaseMetaData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/sql/DatabaseMetaData.java b/jdk/src/share/classes/java/sql/DatabaseMetaData.java index d867986c6bf..1ad5ea17358 100644 --- a/jdk/src/share/classes/java/sql/DatabaseMetaData.java +++ b/jdk/src/share/classes/java/sql/DatabaseMetaData.java @@ -3643,7 +3643,7 @@ public interface DatabaseMetaData extends Wrapper { /** * Retrieves whether a generated key will always be returned if the column - * name(s) or indexe(s) specified for the auto generated key column(s) + * name(s) or index(es) specified for the auto generated key column(s) * are valid and the statement succeeds. The key that is returned may or * may not be based on the column(s) for the auto generated key. * Consult your JDBC driver documentation for additional details. From 1832138a314ec5319fa43e73fa438267f811c6cc Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Fri, 17 Sep 2010 13:33:40 -0400 Subject: [PATCH 04/88] 6985725: RowSetProvider has typo for the property javax.sql.rowset.RowSetFactory in the javadoc Reviewed-by: darcy, ohair --- jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java index 1a84161ce15..b5f9fe74634 100644 --- a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java @@ -29,7 +29,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.SQLException; import java.util.ServiceLoader; -import javax.sql.rowset.RowSetFactory; /** * A factory API that enables applications to obtain a @@ -82,10 +81,10 @@ public class RowSetProvider { * the RowSetFactory implementation class to load:

*
    *
  • - * The System property {@code javax.sql.rowset.RowsetFactory}. For example: + * The System property {@code javax.sql.rowset.RowSetFactory}. For example: *
      *
    • - * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl + * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl *
    • *
    *
  • @@ -271,7 +270,7 @@ public class RowSetProvider { /** * Returns the requested System Property. If a {@code SecurityException} * occurs, just return NULL - * @param propName - System property to retreive + * @param propName - System property to retrieve * @return The System property value or NULL if the property does not exist * or a {@code SecurityException} occurs. */ From 43560f07481407cfd85b7709edcdcc97afa02695 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 17 Sep 2010 22:50:44 +0400 Subject: [PATCH 05/88] 6982661: Complete JLayer component Reviewed-by: malenkov --- .../share/classes/javax/swing/JComponent.java | 11 + jdk/src/share/classes/javax/swing/JLayer.java | 233 +++++++++--------- .../classes/javax/swing/plaf/LayerUI.java | 186 +++++++------- 3 files changed, 211 insertions(+), 219 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java index ae3bddf1182..f94a797ae6c 100644 --- a/jdk/src/share/classes/javax/swing/JComponent.java +++ b/jdk/src/share/classes/javax/swing/JComponent.java @@ -4787,6 +4787,17 @@ public abstract class JComponent extends Container implements Serializable, * @see RepaintManager#addDirtyRegion */ public void repaint(long tm, int x, int y, int width, int height) { + Container p = this; + while ((p = p.getParent()) instanceof JComponent) { + JComponent jp = (JComponent) p; + if (jp.isPaintingOrigin()) { + Rectangle rectangle = SwingUtilities.convertRectangle( + this, new Rectangle(x, y, width, height), jp); + jp.repaint(tm, + rectangle.x, rectangle.y, rectangle.width, rectangle.height); + return; + } + } RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height); } diff --git a/jdk/src/share/classes/javax/swing/JLayer.java b/jdk/src/share/classes/javax/swing/JLayer.java index dd7874c3e70..eab0bf4ab2f 100644 --- a/jdk/src/share/classes/javax/swing/JLayer.java +++ b/jdk/src/share/classes/javax/swing/JLayer.java @@ -25,17 +25,17 @@ package javax.swing; +import sun.awt.AWTAccessor; + import javax.swing.plaf.LayerUI; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; import java.security.AccessController; import java.security.PrivilegedAction; @@ -156,8 +156,6 @@ public final class JLayer private LayerUI layerUI; private JPanel glassPane; private boolean isPainting; - private static final DefaultLayerLayout sharedLayoutInstance = - new DefaultLayerLayout(); private long eventMask; private static final LayerEventController eventController = @@ -165,7 +163,7 @@ public final class JLayer /** * Creates a new {@code JLayer} object with a {@code null} view component - * and {@code null} {@link javax.swing.plaf.LayerUI}. + * and default {@link javax.swing.plaf.LayerUI}. * * @see #setView * @see #setUI @@ -176,14 +174,14 @@ public final class JLayer /** * Creates a new {@code JLayer} object - * with {@code null} {@link javax.swing.plaf.LayerUI}. + * with default {@link javax.swing.plaf.LayerUI}. * * @param view the component to be decorated by this {@code JLayer} * * @see #setUI */ public JLayer(V view) { - this(view, null); + this(view, new LayerUI()); } /** @@ -195,7 +193,6 @@ public final class JLayer * to be used by this {@code JLayer} */ public JLayer(V view, LayerUI ui) { - setLayout(sharedLayoutInstance); setGlassPane(createGlassPane()); setView(view); setUI(ui); @@ -279,10 +276,15 @@ public final class JLayer */ public void setGlassPane(JPanel glassPane) { Component oldGlassPane = getGlassPane(); + boolean isGlassPaneVisible = false; if (oldGlassPane != null) { + isGlassPaneVisible = oldGlassPane.isVisible(); super.remove(oldGlassPane); } if (glassPane != null) { + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane, + new Rectangle()); + glassPane.setVisible(isGlassPaneVisible); super.addImpl(glassPane, null, 0); } this.glassPane = glassPane; @@ -302,6 +304,40 @@ public final class JLayer return new DefaultLayerGlassPane(); } + /** + * Sets the layout manager for this container. This method is + * overridden to prevent the layout manager from being set. + *

    Note: If {@code mgr} is non-{@code null}, this + * method will throw an exception as layout managers are not supported on + * a {@code JLayer}. + * + * @param mgr the specified layout manager + * @exception IllegalArgumentException this method is not supported + */ + public void setLayout(LayoutManager mgr) { + if (mgr != null) { + throw new IllegalArgumentException("JLayer.setLayout() not supported"); + } + } + + /** + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry + * of this component from becoming complex enough to inhibit + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, + * add it to a {@code JPanel} that has a border. + *

    Note: If {@code border} is non-{@code null}, this + * method will throw an exception as borders are not supported on + * a {@code JLayer}. + * + * @param border the {@code Border} to set + * @exception IllegalArgumentException this method is not supported + */ + public void setBorder(Border border) { + if (border != null) { + throw new IllegalArgumentException("JLayer.setBorder() not supported"); + } + } + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} @@ -340,6 +376,32 @@ public final class JLayer setGlassPane(null); } + /** + * Always returns {@code true} to cause painting to originate from {@code JLayer}, + * or one of its ancestors. + * + * @return true + * @see JComponent#isPaintingOrigin() + */ + boolean isPaintingOrigin() { + return true; + } + + /** + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + */ + public void repaint(long tm, int x, int y, int width, int height) { + if (getUI() != null) { + getUI().repaint(tm, x, y, width, height, this); + } + } + /** * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object. * @@ -364,14 +426,18 @@ public final class JLayer } /** - * To enable the correct painting of the {@code glassPane} and view component, - * the {@code JLayer} overrides the default implementation of - * this method to return {@code false} when the {@code glassPane} is visible. + * The {@code JLayer} overrides the default implementation of + * this method (in {@code JComponent}) to return {@code false}. + * This ensures + * that the drawing machinery will call the {@code JLayer}'s + * {@code paint} + * implementation rather than messaging the {@code JLayer}'s + * children directly. * - * @return false if {@code JLayer}'s {@code glassPane} is visible + * @return false */ public boolean isOptimizedDrawingEnabled() { - return glassPane == null || !glassPane.isVisible(); + return false; } /** @@ -461,17 +527,16 @@ public final class JLayer /** * Returns the preferred size of the viewport for a view component. *

    - * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the preferred size of the viewport for a view component * * @see Scrollable - * @see LayerUI#getPreferredScrollableViewportSize(JLayer) */ public Dimension getPreferredScrollableViewportSize() { - if (getUI() != null) { - return getUI().getPreferredScrollableViewportSize(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getPreferredScrollableViewportSize(); } return getPreferredSize(); } @@ -481,18 +546,17 @@ public final class JLayer * that display logical rows or columns in order to completely expose * one block of rows or columns, depending on the value of orientation. *

    - * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the "block" increment for scrolling in the specified direction * * @see Scrollable - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int) */ public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableBlockIncrement(this, visibleRect, + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect, orientation, direction); } return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : @@ -504,17 +568,16 @@ public final class JLayer * determine the height of the layer, unless the preferred height * of the layer is smaller than the height of the viewport. *

    - * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the height of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportHeight(JLayer) */ public boolean getScrollableTracksViewportHeight() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportHeight(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportHeight(); } return false; } @@ -524,17 +587,16 @@ public final class JLayer * determine the width of the layer, unless the preferred width * of the layer is smaller than the width of the viewport. *

    - * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the width of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) */ public boolean getScrollableTracksViewportWidth() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportWidth(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportWidth(); } return false; } @@ -549,20 +611,19 @@ public final class JLayer * Scrolling containers, like {@code JScrollPane}, will use this method * each time the user requests a unit scroll. *

    - * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return The "unit" increment for scrolling in the specified direction. * This value should always be positive. * * @see Scrollable - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int) */ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableUnitIncrement( - this, visibleRect, orientation, direction); + if (getView() instanceof Scrollable) { + return ((Scrollable) getView()).getScrollableUnitIncrement( + visibleRect, orientation, direction); } return 1; } @@ -594,6 +655,16 @@ public final class JLayer eventController.updateAWTEventListener(eventMask, 0); } + /** + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method, + * if {@code LayerUI} is set. + */ + public void doLayout() { + if (getUI() != null) { + getUI().doLayout(this); + } + } + /** * static AWTEventListener to be shared with all AbstractLayerUIs */ @@ -625,8 +696,8 @@ public final class JLayer JLayer l = (JLayer) component; LayerUI ui = l.getUI(); if (ui != null && - isEventEnabled(l.getLayerEventMask(), - event.getID())) { + isEventEnabled(l.getLayerEventMask(), event.getID()) && + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) { ui.eventDispatched(event, l); } } @@ -758,82 +829,4 @@ public final class JLayer return super.contains(x, y); } } - - /** - * The default layout manager for the {@link javax.swing.JLayer}.
    - * It places the glassPane on top of the view component - * and makes it the same size as {@code JLayer}, - * it also makes the view component the same size but minus layer's insets
    - */ - private static class DefaultLayerLayout implements LayoutManager, Serializable { - /** - * {@inheritDoc} - */ - public void layoutContainer(Container parent) { - JLayer layer = (JLayer) parent; - Component view = layer.getView(); - Component glassPane = layer.getGlassPane(); - if (view != null) { - Insets insets = layer.getInsets(); - view.setLocation(insets.left, insets.top); - view.setSize(layer.getWidth() - insets.left - insets.right, - layer.getHeight() - insets.top - insets.bottom); - } - if (glassPane != null) { - glassPane.setLocation(0, 0); - glassPane.setSize(layer.getWidth(), layer.getHeight()); - } - } - - /** - * {@inheritDoc} - */ - public Dimension minimumLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getMinimumSize(); - ret.width += size.width; - ret.height += size.height; - } - if (ret.width == 0 || ret.height == 0) { - ret.width = ret.height = 4; - } - return ret; - } - - /** - * {@inheritDoc} - */ - public Dimension preferredLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getPreferredSize(); - if (size.width > 0 && size.height > 0) { - ret.width += size.width; - ret.height += size.height; - } - } - return ret; - } - - /** - * {@inheritDoc} - */ - public void addLayoutComponent(String name, Component comp) { - } - - /** - * {@inheritDoc} - */ - public void removeLayoutComponent(Component comp) { - } - } } diff --git a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java index 2cfa8e185cc..1fb757313a4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java @@ -599,104 +599,6 @@ public class LayerUI public void applyPropertyChange(PropertyChangeEvent evt, JLayer l) { } - /** - * Returns the preferred size of the viewport for a view component. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return the preferred size of the viewport for a view component - * @see Scrollable#getPreferredScrollableViewportSize() - */ - public Dimension getPreferredScrollableViewportSize(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize(); - } - return l.getPreferredSize(); - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one block of rows or columns, depending on the value of orientation. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return the "block" increment for scrolling in the specified direction - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int) - */ - public int getScrollableBlockIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableBlockIncrement( - visibleRect,orientation, direction); - } - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : - visibleRect.width; - } - - /** - * Returns {@code false} to indicate that the height of the viewport does not - * determine the height of the layer, unless the preferred height - * of the layer is smaller than the height of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the height of the viewport - * @see Scrollable#getScrollableTracksViewportHeight() - */ - public boolean getScrollableTracksViewportHeight(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight(); - } - return false; - } - - /** - * Returns {@code false} to indicate that the width of the viewport does not - * determine the width of the layer, unless the preferred width - * of the layer is smaller than the width of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the width of the viewport - * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) - */ - public boolean getScrollableTracksViewportWidth(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth(); - } - return false; - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one new row or column, depending on the value of orientation. - * Ideally, components should handle a partially exposed row or column - * by returning the distance required to completely expose the item. - *

    - * Scrolling containers, like JScrollPane, will use this method - * each time the user requests a unit scroll. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return The "unit" increment for scrolling in the specified direction. - * This value should always be positive. - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) - */ - public int getScrollableUnitIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - return 1; - } - /** * If the {@code JLayer}'s view component is not {@code null}, * this calls the view's {@code getBaseline()} method. @@ -718,7 +620,7 @@ public class LayerUI /** * If the {@code JLayer}'s view component is not {@code null}, - * this calls the view's {@code getBaselineResizeBehavior()} method. + * this returns the result of the view's {@code getBaselineResizeBehavior()} method. * Otherwise, the default implementation is called. * * @param c {@code JLayer} to return baseline resize behavior for @@ -732,4 +634,90 @@ public class LayerUI } return super.getBaselineResizeBehavior(c); } + + /** + * Causes the passed instance of {@code JLayer} to lay out its components. + * + * @param l the {@code JLayer} component where this UI delegate is being installed + */ + public void doLayout(JLayer l) { + Component view = l.getView(); + if (view != null) { + view.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + Component glassPane = l.getGlassPane(); + if (glassPane != null) { + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getPreferredSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return preferred size for the passed {@code JLayer} + */ + public Dimension getPreferredSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getPreferredSize(); + } + return super.getPreferredSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMinimalSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return minimal size for the passed {@code JLayer} + */ + public Dimension getMinimumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMinimumSize(); + } + return super.getMinimumSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMaximumSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return maximun size for the passed {@code JLayer} + */ + public Dimension getMaximumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMaximumSize(); + } + return super.getMaximumSize(c); + } + + /** + * Adds the specified region to the dirty region list if the component + * is showing. The component will be repainted after all of the + * currently pending events have been dispatched. + *

    + * This method is to be overridden when the dirty region needs to be changed. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + * @see java.awt.Component#isShowing + * @see RepaintManager#addDirtyRegion + */ + public void repaint(long tm, int x, int y, int width, int height, JLayer l) { + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height); + } } From f00f0ea36ce4af5642a944474f5f9ec655439c12 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 17 Sep 2010 23:00:34 +0400 Subject: [PATCH 06/88] 6606019: NPE and IAE are interchanged in specification for GroupLayout.Group class Reviewed-by: rupashka --- jdk/src/share/classes/javax/swing/GroupLayout.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/GroupLayout.java b/jdk/src/share/classes/javax/swing/GroupLayout.java index a343b7bc8a1..7628076a994 100644 --- a/jdk/src/share/classes/javax/swing/GroupLayout.java +++ b/jdk/src/share/classes/javax/swing/GroupLayout.java @@ -1464,8 +1464,8 @@ public class GroupLayout implements LayoutManager2 { * <= {@code pref} <= {@code max}. *

    * Similarly any methods that take a {@code Component} throw a - * {@code NullPointerException} if passed {@code null} and any methods - * that take a {@code Group} throw an {@code IllegalArgumentException} if + * {@code IllegalArgumentException} if passed {@code null} and any methods + * that take a {@code Group} throw an {@code NullPointerException} if * passed {@code null}. * * @see #createSequentialGroup From 80129bc0045db209122907e1d86783c5d42fb337 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 17 Sep 2010 23:09:29 +0400 Subject: [PATCH 07/88] 6632953: MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height Reviewed-by: rupashka --- .../swing/plaf/metal/MetalComboBoxUI.java | 2 +- .../swing/JComboBox/6632953/bug6632953.java | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JComboBox/6632953/bug6632953.java diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java index 77742db410f..e7c811b0c22 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java @@ -144,7 +144,7 @@ public class MetalComboBoxUI extends BasicComboBoxUI { */ public int getBaseline(JComponent c, int width, int height) { int baseline; - if (MetalLookAndFeel.usingOcean()) { + if (MetalLookAndFeel.usingOcean() && height >= 4) { height -= 4; baseline = super.getBaseline(c, width, height); if (baseline >= 0) { diff --git a/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java b/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java new file mode 100644 index 00000000000..90352765eb7 --- /dev/null +++ b/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 6632953 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height + * @author Alexander Potochkin + */ + +import javax.swing.JComboBox; +import javax.swing.plaf.metal.MetalComboBoxUI; + +public class bug6632953 { + + public static void main(String... args) throws Exception { + MetalComboBoxUI ui = new MetalComboBoxUI(); + ui.installUI(new JComboBox()); + ui.getBaseline(new JComboBox(), 0, 0); + ui.getBaseline(new JComboBox(), 1, 1); + ui.getBaseline(new JComboBox(), 2, 2); + ui.getBaseline(new JComboBox(), 3, 3); + ui.getBaseline(new JComboBox(), 4, 4); + } +} From 76501ba258a6ad5e9e05781b13373277ed9347b0 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 17 Sep 2010 23:16:19 +0400 Subject: [PATCH 08/88] 6576054: NullPointerException when closing tooltip by pressing esc Reviewed-by: rupashka --- jdk/src/share/classes/javax/swing/ToolTipManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/javax/swing/ToolTipManager.java b/jdk/src/share/classes/javax/swing/ToolTipManager.java index 17bda0fdcff..ff4aa2c2ac9 100644 --- a/jdk/src/share/classes/javax/swing/ToolTipManager.java +++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java @@ -459,7 +459,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener if (insideComponent == null) { // Drag exit } - if (window != null && event.getSource() == window) { + if (window != null && event.getSource() == window && insideComponent != null) { // if we get an exit and have a heavy window // we need to check if it if overlapping the inside component Container insideComponentWindow = insideComponent.getTopLevelAncestor(); From 1c45f6db9e682fba8d8fe1cbb786a1fd070168da Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 17 Sep 2010 23:21:51 +0400 Subject: [PATCH 09/88] 4330950: Lost newly entered data in the cell when resizing column width Reviewed-by: peterz --- jdk/src/share/classes/javax/swing/JTable.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index bcf00a37547..7842410e772 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -4574,9 +4574,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see TableColumnModelListener */ public void columnMoved(TableColumnModelEvent e) { - // If I'm currently editing, then I should stop editing - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } repaint(); } @@ -4593,8 +4592,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see TableColumnModelListener */ public void columnMarginChanged(ChangeEvent e) { - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } TableColumn resizingColumn = getResizingColumn(); // Need to do this here, before the parent's From db3fbf81801bd1b2ae810fd0fc9d9565a9fb438c Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 17 Sep 2010 23:34:53 +0400 Subject: [PATCH 10/88] 6542335: different behavior on knob of scroll bar between 1.4.2 and 5.0 Reviewed-by: peterz --- .../swing/plaf/basic/BasicScrollBarUI.java | 1 + .../swing/JScrollBar/6542335/bug6542335.java | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index deba91beff3..52204916ce5 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -1603,6 +1603,7 @@ public class BasicScrollBarUI BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue(); oldModel.removeChangeListener(modelListener); newModel.addChangeListener(modelListener); + scrollBarValue = scrollbar.getValue(); scrollbar.repaint(); scrollbar.revalidate(); } else if ("orientation" == propertyName) { diff --git a/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java new file mode 100644 index 00000000000..33e95d8ecac --- /dev/null +++ b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 6542335 + @summary different behavior on knob of scroll bar between 1.4.2 and 5.0 + @author Alexander Potochkin + @run main bug6542335 +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicScrollBarUI; +import java.awt.*; +import java.awt.event.InputEvent; + +public class bug6542335 { + private static JScrollBar sb; + private static MyScrollBarUI ui; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(10); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final JFrame frame = new JFrame("bug6542335"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + sb = new JScrollBar(0, 0, 1, 0, 1); + + ui = new MyScrollBarUI(); + sb.setUI(ui); + + sb.setPreferredSize(new Dimension(200, 17)); + DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel(); + rangeModel.setMaximum(100); + rangeModel.setMinimum(0); + rangeModel.setExtent(50); + rangeModel.setValue(50); + + sb.setModel(rangeModel); + frame.add(sb); + + frame.setSize(200, 100); + frame.setVisible(true); + } + }); + + Rectangle thumbBounds = new Rectangle(ui.getThumbBounds()); + + toolkit.realSync(); + Point l = sb.getLocationOnScreen(); + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (!thumbBounds.equals(ui.getThumbBounds())) { + throw new RuntimeException("Test failed"); + } + } + + static class MyScrollBarUI extends BasicScrollBarUI { + public Rectangle getThumbBounds() { + return super.getThumbBounds(); + } + } +} From d9989f8e0e5d3664d7b7362d2b11763b2495a034 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 17 Sep 2010 14:16:14 -0700 Subject: [PATCH 11/88] 6888546: restore System.initializeSystemClasses Restore System.initializeSystemClasses prior to fix for 6797688 Reviewed-by: alanb --- jdk/src/share/classes/java/lang/System.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index 39c6a5888d1..42431865f25 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -1101,22 +1101,12 @@ public final class System { lineSeparator = props.getProperty("line.separator"); sun.misc.Version.init(); - // Workaround until DownloadManager initialization is revisited. - // Make JavaLangAccess available early enough for internal - // Shutdown hooks to be registered - setJavaLangAccess(); - // Gets and removes system properties that configure the Integer // cache used to support the object identity semantics of autoboxing. // At this time, the size of the cache may be controlled by the // vm option -XX:AutoBoxCacheMax=. Integer.getAndRemoveCacheProperties(); - // Load the zip library now in order to keep java.util.zip.ZipFile - // from trying to use itself to load this library later. - loadLibrary("zip"); - - FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); @@ -1124,6 +1114,10 @@ public final class System { setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); + // Load the zip library now in order to keep java.util.zip.ZipFile + // from trying to use itself to load this library later. + loadLibrary("zip"); + // Setup Java signal handlers for HUP, TERM, and INT (where available). Terminator.setup(); @@ -1153,6 +1147,9 @@ public final class System { // way as other threads; we must do it ourselves here. Thread current = Thread.currentThread(); current.getThreadGroup().add(current); + + // register shared secrets + setJavaLangAccess(); } private static void setJavaLangAccess() { From 11cc8fa5e609bcf9abfc28661372f1d5e8b3731e Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Fri, 17 Sep 2010 14:35:00 -0700 Subject: [PATCH 12/88] 6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx) Do exit status handling before trying to close streams Reviewed-by: alanb, dholmes --- .../classes/java/lang/UNIXProcess.java.linux | 12 ++-- jdk/test/java/lang/ProcessBuilder/Basic.java | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux index 29477f93bbc..b277c2184b5 100644 --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux @@ -176,7 +176,13 @@ final class UNIXProcess extends Process { }}); } - synchronized void processExited(int exitcode) { + void processExited(int exitcode) { + synchronized (this) { + this.exitcode = exitcode; + hasExited = true; + notifyAll(); + } + if (stdout instanceof ProcessPipeInputStream) ((ProcessPipeInputStream) stdout).processExited(); @@ -185,10 +191,6 @@ final class UNIXProcess extends Process { if (stdin instanceof ProcessPipeOutputStream) ((ProcessPipeOutputStream) stdin).processExited(); - - this.exitcode = exitcode; - hasExited = true; - notifyAll(); } public OutputStream getOutputStream() { diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index f4e3c26d9ee..d0bbc1b4a3b 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -1824,6 +1824,64 @@ public class Basic { } } catch (Throwable t) { unexpected(t); } + //---------------------------------------------------------------- + // Check that subprocesses which create subprocesses of their + // own do not cause parent to hang waiting for file + // descriptors to be closed. + //---------------------------------------------------------------- + try { + if (Unix.is() + && new File("/bin/bash").exists() + && new File("/bin/sleep").exists()) { + final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" }; + final ProcessBuilder pb = new ProcessBuilder(cmd); + final Process p = pb.start(); + final InputStream stdout = p.getInputStream(); + final InputStream stderr = p.getErrorStream(); + final OutputStream stdin = p.getOutputStream(); + final Thread reader = new Thread() { + public void run() { + try { stdout.read(); } + catch (IOException e) { + // e.printStackTrace(); + if (EnglishUnix.is() && + ! (e.getMessage().matches(".*Bad file descriptor.*"))) + unexpected(e); + } + catch (Throwable t) { unexpected(t); }}}; + reader.setDaemon(true); + reader.start(); + Thread.sleep(100); + p.destroy(); + // Subprocess is now dead, but file descriptors remain open. + check(p.waitFor() != 0); + check(p.exitValue() != 0); + stdout.close(); + stderr.close(); + stdin.close(); + //---------------------------------------------------------- + // There remain unsolved issues with asynchronous close. + // Here's a highly non-portable experiment to demonstrate: + //---------------------------------------------------------- + if (Boolean.getBoolean("wakeupJeff!")) { + System.out.println("wakeupJeff!"); + // Initialize signal handler for INTERRUPT_SIGNAL. + new FileInputStream("/bin/sleep").getChannel().close(); + // Send INTERRUPT_SIGNAL to every thread in this java. + String[] wakeupJeff = { + "/bin/bash", "-c", + "/bin/ps --noheaders -Lfp $PPID | " + + "/usr/bin/perl -nale 'print $F[3]' | " + + // INTERRUPT_SIGNAL == 62 on my machine du jour. + "/usr/bin/xargs kill -62" + }; + new ProcessBuilder(wakeupJeff).start().waitFor(); + // If wakeupJeff worked, reader probably got EBADF. + reader.join(); + } + } + } catch (Throwable t) { unexpected(t); } + //---------------------------------------------------------------- // Attempt to start process with insufficient permissions fails. //---------------------------------------------------------------- From 07ebbaac23f132e8cfd2cd78730f5da03dfddb78 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Fri, 17 Sep 2010 14:40:38 -0700 Subject: [PATCH 13/88] 6981157: Improve UnknownHostException with EAI error details and other cleanups Generify; remove compiler warnings, typos, casts; return status information via gai_strerror when getaddrinfo fails; show full stack of native failures Reviewed-by: michaelm, alanb --- .../share/classes/java/net/InetAddress.java | 155 +++++++++--------- .../native/java/net/Inet6AddressImpl.c | 19 +-- jdk/src/solaris/native/java/net/net_util_md.c | 32 +++- jdk/src/solaris/native/java/net/net_util_md.h | 10 +- 4 files changed, 121 insertions(+), 95 deletions(-) diff --git a/jdk/src/share/classes/java/net/InetAddress.java b/jdk/src/share/classes/java/net/InetAddress.java index 96a17482d8f..c4ace57995f 100644 --- a/jdk/src/share/classes/java/net/InetAddress.java +++ b/jdk/src/share/classes/java/net/InetAddress.java @@ -677,19 +677,20 @@ class InetAddress implements java.io.Serializable { static InetAddressImpl impl; - private static HashMap lookupTable = new HashMap(); + private static HashMap lookupTable + = new HashMap(); /** * Represents a cache entry */ static final class CacheEntry { - CacheEntry(Object address, long expiration) { - this.address = address; + CacheEntry(InetAddress[] addresses, long expiration) { + this.addresses = addresses; this.expiration = expiration; } - Object address; + InetAddress[] addresses; long expiration; } @@ -698,7 +699,7 @@ class InetAddress implements java.io.Serializable { * at creation time. */ static final class Cache { - private LinkedHashMap cache; + private LinkedHashMap cache; private Type type; enum Type {Positive, Negative}; @@ -708,7 +709,7 @@ class InetAddress implements java.io.Serializable { */ public Cache(Type type) { this.type = type; - cache = new LinkedHashMap(); + cache = new LinkedHashMap(); } private int getPolicy() { @@ -724,7 +725,7 @@ class InetAddress implements java.io.Serializable { * entry then for this host then the entry will be * replaced. */ - public Cache put(String host, Object address) { + public Cache put(String host, InetAddress[] addresses) { int policy = getPolicy(); if (policy == InetAddressCachePolicy.NEVER) { return this; @@ -736,12 +737,10 @@ class InetAddress implements java.io.Serializable { // As we iterate in insertion order we can // terminate when a non-expired entry is found. - LinkedList expired = new LinkedList(); - Iterator i = cache.keySet().iterator(); + LinkedList expired = new LinkedList(); long now = System.currentTimeMillis(); - while (i.hasNext()) { - String key = (String)i.next(); - CacheEntry entry = (CacheEntry)cache.get(key); + for (String key : cache.keySet()) { + CacheEntry entry = cache.get(key); if (entry.expiration >= 0 && entry.expiration < now) { expired.add(key); @@ -750,9 +749,8 @@ class InetAddress implements java.io.Serializable { } } - i = expired.iterator(); - while (i.hasNext()) { - cache.remove(i.next()); + for (String key : expired) { + cache.remove(key); } } @@ -766,7 +764,7 @@ class InetAddress implements java.io.Serializable { } else { expiration = System.currentTimeMillis() + (policy * 1000); } - CacheEntry entry = new CacheEntry(address, expiration); + CacheEntry entry = new CacheEntry(addresses, expiration); cache.put(host, entry); return this; } @@ -780,7 +778,7 @@ class InetAddress implements java.io.Serializable { if (policy == InetAddressCachePolicy.NEVER) { return null; } - CacheEntry entry = (CacheEntry)cache.get(host); + CacheEntry entry = cache.get(host); // check if entry has expired if (entry != null && policy != InetAddressCachePolicy.FOREVER) { @@ -814,42 +812,41 @@ class InetAddress implements java.io.Serializable { } /* - * Cache the given hostname and address. + * Cache the given hostname and addresses. */ - private static void cacheAddress(String hostname, Object address, - boolean success) { + private static void cacheAddresses(String hostname, + InetAddress[] addresses, + boolean success) { hostname = hostname.toLowerCase(); synchronized (addressCache) { cacheInitIfNeeded(); if (success) { - addressCache.put(hostname, address); + addressCache.put(hostname, addresses); } else { - negativeCache.put(hostname, address); + negativeCache.put(hostname, addresses); } } } /* * Lookup hostname in cache (positive & negative cache). If - * found return address, null if not found. + * found return addresses, null if not found. */ - private static Object getCachedAddress(String hostname) { + private static InetAddress[] getCachedAddresses(String hostname) { hostname = hostname.toLowerCase(); // search both positive & negative caches synchronized (addressCache) { - CacheEntry entry; - cacheInitIfNeeded(); - entry = addressCache.get(hostname); + CacheEntry entry = addressCache.get(hostname); if (entry == null) { entry = negativeCache.get(hostname); } if (entry != null) { - return entry.address; + return entry.addresses; } } @@ -911,7 +908,7 @@ class InetAddress implements java.io.Serializable { static { // create the impl - impl = (new InetAddressImplFactory()).create(); + impl = InetAddressImplFactory.create(); // get name service if provided and requested String provider = null;; @@ -931,7 +928,7 @@ class InetAddress implements java.io.Serializable { } // if not designate any name services provider, - // creat a default one + // create a default one if (nameServices.size() == 0) { NameService ns = createNSProvider("default"); nameServices.add(ns); @@ -939,7 +936,7 @@ class InetAddress implements java.io.Serializable { } /** - * Create an InetAddress based on the provided host name and IP address + * Creates an InetAddress based on the provided host name and IP address. * No name service is checked for the validity of the address. * *

    The host name can either be a machine name, such as @@ -1067,13 +1064,13 @@ class InetAddress implements java.io.Serializable { boolean ipv6Expected = false; if (host.charAt(0) == '[') { - // This is supposed to be an IPv6 litteral + // This is supposed to be an IPv6 literal if (host.length() > 2 && host.charAt(host.length()-1) == ']') { host = host.substring(1, host.length() -1); ipv6Expected = true; } else { // This was supposed to be a IPv6 address, but it's not! - throw new UnknownHostException(host); + throw new UnknownHostException(host + ": invalid IPv6 address"); } } @@ -1180,8 +1177,6 @@ class InetAddress implements java.io.Serializable { throws UnknownHostException { /* If it gets here it is presumed to be a hostname */ /* Cache.get can return: null, unknownAddress, or InetAddress[] */ - Object obj = null; - Object objcopy = null; /* make sure the connection to the host is allowed, before we * give out a hostname @@ -1193,26 +1188,23 @@ class InetAddress implements java.io.Serializable { } } - obj = getCachedAddress(host); + InetAddress[] addresses = getCachedAddresses(host); /* If no entry in cache, then do the host lookup */ - if (obj == null) { - obj = getAddressFromNameService(host); + if (addresses == null) { + addresses = getAddressesFromNameService(host); } - if (obj == unknown_array) + if (addresses == unknown_array) throw new UnknownHostException(host); - /* Make a copy of the InetAddress array */ - objcopy = ((InetAddress [])obj).clone(); - - return (InetAddress [])objcopy; + return addresses.clone(); } - private static Object getAddressFromNameService(String host) + private static InetAddress[] getAddressesFromNameService(String host) throws UnknownHostException { - Object obj = null; + InetAddress[] addresses = null; boolean success = false; UnknownHostException ex = null; @@ -1226,16 +1218,16 @@ class InetAddress implements java.io.Serializable { // would be blocked until the host is removed // from the lookupTable. Then this thread // should try to look up the addressCache. - // i) if it found the address in the + // i) if it found the addresses in the // addressCache, checkLookupTable() would - // return the address. - // ii) if it didn't find the address in the + // return the addresses. + // ii) if it didn't find the addresses in the // addressCache for any reason, // it should add the host in the // lookupTable and return null so the // following code would do a lookup itself. - if ((obj = checkLookupTable(host)) == null) { - // This is the first thread which looks up the address + if ((addresses = checkLookupTable(host)) == null) { + // This is the first thread which looks up the addresses // this host or the cache entry for this host has been // expired so this thread should do the lookup. for (NameService nameService : nameServices) { @@ -1246,26 +1238,26 @@ class InetAddress implements java.io.Serializable { * allocating space when the lookup fails. */ - obj = nameService.lookupAllHostAddr(host); + addresses = nameService.lookupAllHostAddr(host); success = true; break; } catch (UnknownHostException uhe) { if (host.equalsIgnoreCase("localhost")) { InetAddress[] local = new InetAddress[] { impl.loopbackAddress() }; - obj = local; + addresses = local; success = true; break; } else { - obj = unknown_array; + addresses = unknown_array; success = false; ex = uhe; } } } - // Cache the address. - cacheAddress(host, obj, success); + // Cache the addresses. + cacheAddresses(host, addresses, success); // Delete the host from the lookupTable, and // notify all threads waiting for the monitor // for lookupTable. @@ -1274,13 +1266,13 @@ class InetAddress implements java.io.Serializable { throw ex; } - return obj; + return addresses; } - private static Object checkLookupTable(String host) { - // make sure obj is null. - Object obj = null; + private static InetAddress[] checkLookupTable(String host) { + // make sure addresses is null. + InetAddress[] addresses = null; synchronized (lookupTable) { // If the host isn't in the lookupTable, add it in the @@ -1288,11 +1280,11 @@ class InetAddress implements java.io.Serializable { // the lookup. if (lookupTable.containsKey(host) == false) { lookupTable.put(host, null); - return obj; + return addresses; } // If the host is in the lookupTable, it means that another - // thread is trying to look up the address of this host. + // thread is trying to look up the addresses of this host. // This thread should wait. while (lookupTable.containsKey(host)) { try { @@ -1302,18 +1294,18 @@ class InetAddress implements java.io.Serializable { } } - // The other thread has finished looking up the address of - // the host. This thread should retry to get the address - // from the addressCache. If it doesn't get the address from - // the cache, it will try to look up the address itself. - obj = getCachedAddress(host); - if (obj == null) { + // The other thread has finished looking up the addresses of + // the host. This thread should retry to get the addresses + // from the addressCache. If it doesn't get the addresses from + // the cache, it will try to look up the addresses itself. + addresses = getCachedAddresses(host); + if (addresses == null) { synchronized (lookupTable) { lookupTable.put(host, null); } } - return obj; + return addresses; } private static void updateLookupTable(String host) { @@ -1396,15 +1388,20 @@ class InetAddress implements java.io.Serializable { cachedLocalHost = null; } - // we are calling getAddressFromNameService directly + // we are calling getAddressesFromNameService directly // to avoid getting localHost from cache if (ret == null) { InetAddress[] localAddrs; try { localAddrs = - (InetAddress[]) InetAddress.getAddressFromNameService(local); + InetAddress.getAddressesFromNameService(local); } catch (UnknownHostException uhe) { - throw new UnknownHostException(local + ": " + uhe.getMessage()); + // Rethrow with a more informative error message. + UnknownHostException uhe2 = + new UnknownHostException(local + ": " + + uhe.getMessage()); + uhe2.initCause(uhe); + throw uhe2; } cachedLocalHost = localAddrs[0]; cacheTime = now; @@ -1434,8 +1431,8 @@ class InetAddress implements java.io.Serializable { /* * Load and instantiate an underlying impl class */ - static Object loadImpl(String implName) { - Object impl; + static InetAddressImpl loadImpl(String implName) { + Object impl = null; /* * Property "impl.prefix" will be prepended to the classname @@ -1446,7 +1443,6 @@ class InetAddress implements java.io.Serializable { */ String prefix = AccessController.doPrivileged( new GetPropertyAction("impl.prefix", "")); - impl = null; try { impl = Class.forName("java.net." + prefix + implName).newInstance(); } catch (ClassNotFoundException e) { @@ -1471,7 +1467,7 @@ class InetAddress implements java.io.Serializable { } } - return impl; + return (InetAddressImpl) impl; } private void readObjectNoData (ObjectInputStream s) throws @@ -1498,13 +1494,8 @@ class InetAddress implements java.io.Serializable { class InetAddressImplFactory { static InetAddressImpl create() { - Object o; - if (isIPv6Supported()) { - o = InetAddress.loadImpl("Inet6AddressImpl"); - } else { - o = InetAddress.loadImpl("Inet4AddressImpl"); - } - return (InetAddressImpl)o; + return InetAddress.loadImpl(isIPv6Supported() ? + "Inet6AddressImpl" : "Inet4AddressImpl"); } static native boolean isIPv6Supported(); diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c index 58926062eff..4c5e928c560 100644 --- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c @@ -124,7 +124,7 @@ static jfieldID ni_ia6ipaddressID; static int initialized = 0; /* - * Find an internet address for a given hostname. Not this this + * Find an internet address for a given hostname. Note that this * code only works for addresses of type INET. The translation * of %d.%d.%d.%d to an address (int) occurs in java now, so the * String "host" shouldn't *ever* be a %d.%d.%d.%d string @@ -200,7 +200,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, */ if (isspace((unsigned char)hostname[0])) { JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", - (char *)hostname); + hostname); JNU_ReleaseStringPlatformChars(env, host, hostname); return NULL; } @@ -210,8 +210,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, if (error) { /* report error */ - JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", - (char *)hostname); + ThrowUnknownHostExceptionWithGaiError(env, hostname, error); JNU_ReleaseStringPlatformChars(env, host, hostname); return NULL; } else { @@ -407,7 +406,7 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this, addr |= ((caddr[1] <<16) & 0xff0000); addr |= ((caddr[2] <<8) & 0xff00); addr |= (caddr[3] & 0xff); - memset((char *) &him4, 0, sizeof(him4)); + memset((void *) &him4, 0, sizeof(him4)); him4.sin_addr.s_addr = (uint32_t) htonl(addr); him4.sin_family = AF_INET; sa = (struct sockaddr *) &him4; @@ -417,7 +416,7 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this, * For IPv6 address construct a sockaddr_in6 structure. */ (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr); - memset((char *) &him6, 0, sizeof(him6)); + memset((void *) &him6, 0, sizeof(him6)); memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) ); him6.sin6_family = AF_INET6; sa = (struct sockaddr *) &him6 ; @@ -579,8 +578,8 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this, ifArray, ttl); } - memset((char *) caddr, 0, 16); - memset((char *) &him6, 0, sizeof(him6)); + memset((void *) caddr, 0, 16); + memset((void *) &him6, 0, sizeof(him6)); (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr); memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) ); him6.sin6_family = AF_INET6; @@ -600,8 +599,8 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this, * for it. */ if (!(IS_NULL(ifArray))) { - memset((char *) caddr, 0, 16); - memset((char *) &inf6, 0, sizeof(inf6)); + memset((void *) caddr, 0, 16); + memset((void *) &inf6, 0, sizeof(inf6)); (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr); memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) ); inf6.sin6_family = AF_INET6; diff --git a/jdk/src/solaris/native/java/net/net_util_md.c b/jdk/src/solaris/native/java/net/net_util_md.c index 1a5283cfb3b..8a414e60141 100644 --- a/jdk/src/solaris/native/java/net/net_util_md.c +++ b/jdk/src/solaris/native/java/net/net_util_md.c @@ -61,6 +61,7 @@ getaddrinfo_f getaddrinfo_ptr = NULL; freeaddrinfo_f freeaddrinfo_ptr = NULL; +gai_strerror_f gai_strerror_ptr = NULL; getnameinfo_f getnameinfo_ptr = NULL; /* @@ -342,11 +343,14 @@ jint IPv6_supported() freeaddrinfo_ptr = (freeaddrinfo_f) JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo"); + gai_strerror_ptr = (gai_strerror_f) + JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror"); + getnameinfo_ptr = (getnameinfo_f) JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo"); if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) { - /* Wee need all 3 of them */ + /* We need all 3 of them */ getaddrinfo_ptr = NULL; } @@ -355,6 +359,32 @@ jint IPv6_supported() #endif /* AF_INET6 */ } +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, + const char* hostname, + int gai_error) +{ + const char *format = "%s: %s"; + const char *error_string = + (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error); + if (error_string == NULL) + error_string = "unknown error"; + + int size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; + char *buf = (char *) malloc(size); + if (buf) { + sprintf(buf, format, hostname, error_string); + jstring s = JNU_NewStringPlatform(env, buf); + if (s != NULL) { + jobject x = JNU_NewObjectByName(env, + "java/net/UnknownHostException", + "(Ljava/lang/String;)V", s); + if (x != NULL) + (*env)->Throw(env, x); + } + free(buf); + } +} + void NET_AllocSockaddr(struct sockaddr **him, int *len) { #ifdef AF_INET6 diff --git a/jdk/src/solaris/native/java/net/net_util_md.h b/jdk/src/solaris/native/java/net/net_util_md.h index 13101dce13b..97f2ffa30b0 100644 --- a/jdk/src/solaris/native/java/net/net_util_md.h +++ b/jdk/src/solaris/native/java/net/net_util_md.h @@ -84,11 +84,13 @@ int getDefaultIPv6Interface(struct in6_addr *target_addr); /* needed from libsocket on Solaris 8 */ -typedef int (*getaddrinfo_f)(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res); +typedef int (*getaddrinfo_f)(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); typedef void (*freeaddrinfo_f)(struct addrinfo *); +typedef const char * (*gai_strerror_f)(int ecode); + typedef int (*getnameinfo_f)(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); @@ -96,6 +98,10 @@ extern getaddrinfo_f getaddrinfo_ptr; extern freeaddrinfo_f freeaddrinfo_ptr; extern getnameinfo_f getnameinfo_ptr; +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, + const char* hostname, + int gai_error); + /* do we have address translation support */ extern jboolean NET_addrtransAvailable(); From 11bbc5d5bc12d2104c66d92f96184ead11d36a89 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Sat, 18 Sep 2010 06:09:48 -0400 Subject: [PATCH 14/88] 6984044: RowSet source needs to rebrand vendor references Reviewed-by: darcy, ohair --- .../com/sun/rowset/internal/WebRowSetXmlWriter.java | 2 +- .../com/sun/rowset/providers/RIOptimisticProvider.java | 8 ++++---- .../classes/com/sun/rowset/providers/RIXMLProvider.java | 4 ++-- jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java | 3 +-- jdk/src/share/classes/javax/sql/rowset/WebRowSet.java | 6 +++--- jdk/src/share/classes/javax/sql/rowset/rowset.properties | 4 ++-- .../share/classes/javax/sql/rowset/spi/SyncFactory.java | 6 +++--- .../share/classes/javax/sql/rowset/spi/SyncProvider.java | 4 ++-- jdk/src/share/classes/javax/sql/rowset/spi/package.html | 4 ++-- 9 files changed, 20 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java index f0d59647a7f..7dea5d97c77 100644 --- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java +++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java @@ -248,7 +248,7 @@ public class WebRowSetXmlWriter implements XmlWriter, Serializable { String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@")); propString("sync-provider-name", strProvider); - propString("sync-provider-vendor", "Sun Microsystems Inc."); + propString("sync-provider-vendor", "Oracle Corporation"); propString("sync-provider-version", "1.0"); propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade()); propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock()); diff --git a/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java b/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java index 5fb04167366..0d8dff3232f 100644 --- a/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java +++ b/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java @@ -93,14 +93,14 @@ public final class RIOptimisticProvider extends SyncProvider implements Serializ private CachedRowSetWriter writer; /** - * The unique provider indentifier. + * The unique provider identifier. */ private String providerID = "com.sun.rowset.providers.RIOptimisticProvider"; /** * The vendor name of this SyncProvider implementation */ - private String vendorName = "Sun Microsystems Inc."; + private String vendorName = "Oracle Corporation"; /** * The version number of this SyncProvider implementation @@ -236,8 +236,8 @@ public final class RIOptimisticProvider extends SyncProvider implements Serializ } /** - * Returns the vendor name of the Reference Implemntation Optimistic - * Syncchronication Provider + * Returns the vendor name of the Reference Implementation Optimistic + * Synchronization Provider * * @return the String detailing the vendor name of this * SyncProvider diff --git a/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java b/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java index bbe2bdc5436..3736001cca2 100644 --- a/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java +++ b/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ public final class RIXMLProvider extends SyncProvider { /** * The vendor name of this SyncProvider implementation. */ - private String vendorName = "Sun Microsystems Inc."; + private String vendorName = "Oracle Corporation"; /** * The version number of this SyncProvider implementation. diff --git a/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java b/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java index 2a60bb3b7e7..7861223911b 100644 --- a/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java +++ b/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java @@ -39,7 +39,7 @@ import javax.sql.rowset.spi.*; * CachedRowSet must implement. *

    * The reference implementation of the CachedRowSet interface provided - * by Sun Microsystems is a standard implementation. Developers may use this implementation + * by Oracle Corporation is a standard implementation. Developers may use this implementation * just as it is, they may extend it, or they may choose to write their own implementations * of this interface. *

    @@ -1623,4 +1623,3 @@ public interface CachedRowSet extends RowSet, Joinable { public boolean previousPage() throws SQLException; } - diff --git a/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java b/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java index c354c5fe7bb..abef62f1271 100644 --- a/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java +++ b/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ import org.xml.sax.*; * <url>jdbc:thin:oracle</url> * <sync-provider> * <sync-provider-name>.com.rowset.provider.RIOptimisticProvider</sync-provider-name> - * <sync-provider-vendor>Sun Microsystems</sync-provider-vendor> + * <sync-provider-vendor>Oracle Corporation</sync-provider-vendor> * <sync-provider-version>1.0</sync-provider-name> * <sync-provider-grade>LOW</sync-provider-grade> * <data-source-lock>NONE</data-source-lock> @@ -489,7 +489,7 @@ public interface WebRowSet extends CachedRowSet { * tags and their valid values for a WebRowSet implementation. */ public static String PUBLIC_XML_SCHEMA = - "--//Sun Microsystems, Inc.//XSD Schema//EN"; + "--//Oracle Corporation//XSD Schema//EN"; /** * The URL for the XML Schema definition file that defines the XML tags and diff --git a/jdk/src/share/classes/javax/sql/rowset/rowset.properties b/jdk/src/share/classes/javax/sql/rowset/rowset.properties index 4fb38bd5242..68dd95b0fb7 100644 --- a/jdk/src/share/classes/javax/sql/rowset/rowset.properties +++ b/jdk/src/share/classes/javax/sql/rowset/rowset.properties @@ -3,10 +3,10 @@ # Optimistic synchonriztaion provider rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider -rowset.provider.vendor.0=Sun Microsystems Inc +rowset.provider.vendor.0=Oracle Corporation rowset.provider.version.0=1.0 # XML Provider using standard XML schema rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider -rowset.provider.vendor.1=Sun Microsystems Inc. +rowset.provider.vendor.1=Oracle Corporation rowset.provider.version.1=1.0 diff --git a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java index 4aec879a059..3369f466b41 100644 --- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java @@ -125,12 +125,12 @@ import javax.naming.*; * * # Optimistic synchronization provider * rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider - * rowset.provider.vendor.0=Sun Microsystems Inc + * rowset.provider.vendor.0=Oracle Corporation * rowset.provider.version.0=1.0 * * # XML Provider using standard XML schema * rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider - * rowset.provider.vendor.1=Sun Microsystems Inc. + * rowset.provider.vendor.1=Oracle Corporation * rowset.provider.version.1=1.0 * * The SyncFactory checks this file and registers the @@ -369,7 +369,7 @@ public class SyncFactory { try { // check if user is supplying his Synchronisation Provider - // Implementation if not use Sun's implementation. + // Implementation if not using Oracle's implementation. // properties.load(new FileInputStream(ROWSET_PROPERTIES)); // The rowset.properties needs to be in jdk/jre/lib when diff --git a/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java b/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java index 86a4bcd28e3..81425998889 100644 --- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java @@ -91,8 +91,8 @@ import javax.sql.*; * *

    * A vendor can register a SyncProvider implementation class name - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com. - * Sun will maintain a database listing the + * with Oracle Corporation by sending email to jdbc@sun.com. + * Oracle will maintain a database listing the * available SyncProvider implementations for use with compliant * RowSet implementations. This database will be similar to the * one already maintained to list available JDBC drivers. diff --git a/jdk/src/share/classes/javax/sql/rowset/spi/package.html b/jdk/src/share/classes/javax/sql/rowset/spi/package.html index 89a84a39715..a5732719108 100644 --- a/jdk/src/share/classes/javax/sql/rowset/spi/package.html +++ b/jdk/src/share/classes/javax/sql/rowset/spi/package.html @@ -8,7 +8,7 @@ - - - - - - + + - - - + - + - + - + Must set property 'includes' - - - - - + - + Must set property 'run.classname' - + - - - + @@ -118,7 +118,7 @@ - + @@ -127,36 +127,36 @@ - + Some tests failed; see report for details. - + - + - + Must set property 'debug.classname' - + Must set property 'jtreg.tests' - + - + Must set property 'class' @@ -169,16 +169,16 @@ - + - - - + @@ -187,7 +187,7 @@ - + @@ -196,26 +196,26 @@ - + - + - + - - + - @@ -236,7 +236,7 @@ - + @@ -251,28 +251,29 @@ - - + - + From f788ac2dbde54ab88595242de3df3f4e4437199a Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 23 Sep 2010 10:46:03 +0800 Subject: [PATCH 27/88] 6982971: TEST failure: com/sun/security/sasl/ntlm/NTLMTest.java Reviewed-by: wetmore --- jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java b/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java index 64a5f8e54e2..64f5eae184c 100644 --- a/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java +++ b/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java @@ -31,8 +31,6 @@ import javax.security.sasl.*; import javax.security.auth.callback.*; import java.util.*; -import com.sun.security.ntlm.NTLMException; - public class NTLMTest { private static final String MECH = "NTLM"; @@ -95,19 +93,13 @@ public class NTLMTest { checkVersion("LM/NTLM", "LMv2"); throw new Exception("Should not succeed"); } catch (SaslException se) { - NTLMException ne = (NTLMException)se.getCause(); - if (ne.errorCode() != NTLMException.AUTH_FAILED) { - throw new Exception("Failed false"); - } + // OK } try { checkVersion("LMv2/NTLMv2", "LM"); throw new Exception("Should not succeed"); } catch (SaslException se) { - NTLMException ne = (NTLMException)se.getCause(); - if (ne.errorCode() != NTLMException.AUTH_FAILED) { - throw new Exception("Failed false"); - } + // OK } } From 872a9b93033b066d9a9969163967b47e7012691a Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Wed, 22 Sep 2010 21:44:18 -0700 Subject: [PATCH 28/88] 6984036: servicetag vendor rebranding issues Update product_vendor field to use java.vendor system property Reviewed-by: ohair --- .../share/classes/com/sun/servicetag/Installer.java | 10 ++++++---- .../classes/com/sun/servicetag/RegistrationData.java | 4 ++-- jdk/src/share/classes/com/sun/servicetag/Registry.java | 2 +- .../com/sun/servicetag/SolarisSystemEnvironment.java | 7 ++++--- jdk/test/com/sun/servicetag/JavaServiceTagTest.java | 3 ++- jdk/test/com/sun/servicetag/JavaServiceTagTest1.java | 4 +++- jdk/test/com/sun/servicetag/Util.java | 2 ++ jdk/test/com/sun/servicetag/environ.properties | 4 ++-- jdk/test/com/sun/servicetag/missing-environ-field.xml | 4 ++-- jdk/test/com/sun/servicetag/newer-registry-version.xml | 2 +- jdk/test/com/sun/servicetag/registration.xml | 10 +++++----- jdk/test/com/sun/servicetag/servicetag1.properties | 2 +- jdk/test/com/sun/servicetag/servicetag2.properties | 2 +- jdk/test/com/sun/servicetag/servicetag3.properties | 2 +- jdk/test/com/sun/servicetag/servicetag4.properties | 2 +- jdk/test/com/sun/servicetag/servicetag5.properties | 2 +- 16 files changed, 35 insertions(+), 27 deletions(-) diff --git a/jdk/src/share/classes/com/sun/servicetag/Installer.java b/jdk/src/share/classes/com/sun/servicetag/Installer.java index 2c8476e71f8..ae5ed4bc4fb 100644 --- a/jdk/src/share/classes/com/sun/servicetag/Installer.java +++ b/jdk/src/share/classes/com/sun/servicetag/Installer.java @@ -43,7 +43,8 @@ public class Installer { "servicetag.dir.path"; private static String SVCTAG_ENABLE_REGISTRATION = "servicetag.registration.enabled"; - private final static String SUN_VENDOR = "Sun Microsystems"; + private final static String ORACLE = "Oracle"; + private final static String SUN = "Sun Microsystems"; private final static String REGISTRATION_XML = "registration.xml"; private final static String SERVICE_TAG_FILE = "servicetag"; private final static String REGISTRATION_HTML_NAME = "register"; @@ -84,9 +85,10 @@ public class Installer { // Implementation of ServiceTag.getJavaServiceTag(String) method static ServiceTag getJavaServiceTag(String source) throws IOException { - if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) { + String vendor = System.getProperty("java.vendor", ""); + if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) { // Products bundling this implementation may run on - // Mac OS which is not a Sun JDK + // Mac OS which is not a Sun/Oracle JDK return null; } boolean cleanup = false; @@ -365,7 +367,7 @@ public class Installer { props.getProperty("servicetag.parent.name"), props.getProperty("servicetag.parent.urn"), getProductDefinedId(), - SUN_VENDOR, + System.getProperty("java.vendor"), System.getProperty("os.arch"), getZoneName(), svcTagSource); diff --git a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java index 99f5623d145..1c203f4126c 100644 --- a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java +++ b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java @@ -80,12 +80,12 @@ import static com.sun.servicetag.RegistrationDocument.*; * * systemManufacturer * System manufacturer - * e.g. Sun Microsystems + * e.g. Oracle Corporation * * * cpuManufacturer * CPU manufacturer - * e.g. Sun Microsystems + * e.g. Oracle Corporation * * * serialNumber diff --git a/jdk/src/share/classes/com/sun/servicetag/Registry.java b/jdk/src/share/classes/com/sun/servicetag/Registry.java index 14ad2fd623d..505ac64c629 100644 --- a/jdk/src/share/classes/com/sun/servicetag/Registry.java +++ b/jdk/src/share/classes/com/sun/servicetag/Registry.java @@ -90,7 +90,7 @@ public class Registry { stclient = getWindowsStClientFile(); } else { if (isVerbose()) { - System.out.println("Running on non-Sun JDK"); + System.out.println("Running on unsupported platform"); } } initialized = true; diff --git a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java index 3cfd556a1fd..19cbae0b4a1 100644 --- a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java +++ b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java @@ -44,6 +44,7 @@ import java.io.*; * Solaris implementation of the SystemEnvironment class. */ class SolarisSystemEnvironment extends SystemEnvironment { + private static final String ORACLE = "Oracle Corporation"; SolarisSystemEnvironment() { setHostId(getCommandOutput("/usr/bin/hostid")); setSystemModel(getCommandOutput("/usr/bin/uname", "-i")); @@ -59,7 +60,7 @@ class SolarisSystemEnvironment extends SystemEnvironment { private String getSolarisCpuManufacturer() { // not fully accurate, this could be another manufacturer (fujitsu for example) if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return "Sun Microsystems, Inc"; + return ORACLE; } // if we're here, then we'll try smbios (type 4) @@ -73,7 +74,7 @@ class SolarisSystemEnvironment extends SystemEnvironment { private String getSolarisSystemManufacturer() { // not fully accurate, this could be another manufacturer (fujitsu for example) if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return "Sun Microsystems, Inc"; + return ORACLE; } // if we're here, then we'll try smbios (type 1) @@ -117,7 +118,7 @@ class SolarisSystemEnvironment extends SystemEnvironment { // ID SIZE TYPE // 1 150 SMB_TYPE_SYSTEM (system information) // - // Manufacturer: Sun Microsystems + // Manufacturer: Oracle Corporation // Product: Sun Fire X4600 // Version: To Be Filled By O.E.M. // Serial Number: 00:14:4F:45:0C:2A diff --git a/jdk/test/com/sun/servicetag/JavaServiceTagTest.java b/jdk/test/com/sun/servicetag/JavaServiceTagTest.java index 6ac19cd9fe0..0ebe0d5d895 100644 --- a/jdk/test/com/sun/servicetag/JavaServiceTagTest.java +++ b/jdk/test/com/sun/servicetag/JavaServiceTagTest.java @@ -124,8 +124,9 @@ public class JavaServiceTagTest { throw new RuntimeException("Unexpected platform_arch: " + st.getPlatformArch()); } + String vendor = System.getProperty("java.vendor"); if (!st.getProductVendor(). - equals("Sun Microsystems")) { + equals(vendor)) { throw new RuntimeException("Unexpected product_vendor: " + st.getProductVendor()); } diff --git a/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java b/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java index 00713f999de..3bb0328ade8 100644 --- a/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java +++ b/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java @@ -196,8 +196,10 @@ public class JavaServiceTagTest1 { throw new RuntimeException("Unexpected platform_arch: " + st.getPlatformArch()); } + + String vendor = System.getProperty("java.vendor"); if (!st.getProductVendor(). - equals("Sun Microsystems")) { + equals(vendor)) { throw new RuntimeException("Unexpected product_vendor: " + st.getProductVendor()); } diff --git a/jdk/test/com/sun/servicetag/Util.java b/jdk/test/com/sun/servicetag/Util.java index 77bc7da8355..cf75c2c8fd3 100644 --- a/jdk/test/com/sun/servicetag/Util.java +++ b/jdk/test/com/sun/servicetag/Util.java @@ -162,6 +162,8 @@ public class Util { for (ServiceTag st : svcTags) { ServiceTag st1 = stMap.get(st.getInstanceURN()); if (!matches(st, st1)) { + System.err.println(st); + System.err.println(st1); throw new RuntimeException("ServiceTag in the registry " + "does not match the one in the map"); } diff --git a/jdk/test/com/sun/servicetag/environ.properties b/jdk/test/com/sun/servicetag/environ.properties index 0881061b0ea..22163e587d8 100644 --- a/jdk/test/com/sun/servicetag/environ.properties +++ b/jdk/test/com/sun/servicetag/environ.properties @@ -4,6 +4,6 @@ osName=SunOS osVersion=5.10 osArchitecture=sparc systemModel=Sun-Fire-V440 -systemManufacturer=Sun Microsystems -cpuManufacturer=Sun Microsystems +systemManufacturer=Oracle Corporation +cpuManufacturer=Oracle Corporation serialNumber=BEL078932 diff --git a/jdk/test/com/sun/servicetag/missing-environ-field.xml b/jdk/test/com/sun/servicetag/missing-environ-field.xml index 727288dd10a..775bbaab1b3 100644 --- a/jdk/test/com/sun/servicetag/missing-environ-field.xml +++ b/jdk/test/com/sun/servicetag/missing-environ-field.xml @@ -19,7 +19,7 @@ urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 Java Platform Standard Edition 6 (Java SE 6) id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -Sun Microsystems +Oracle Corporation sparc 2007-11-12 06:15:11 GMT global @@ -34,7 +34,7 @@ urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 Java Platform Standard Edition 6 (Java SE 6) id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586 -Sun Microsystems +Oracle Corporation i386 2007-11-12 06:15:11 GMT global diff --git a/jdk/test/com/sun/servicetag/newer-registry-version.xml b/jdk/test/com/sun/servicetag/newer-registry-version.xml index 9ee68ac0afc..fe9fdf3bdec 100644 --- a/jdk/test/com/sun/servicetag/newer-registry-version.xml +++ b/jdk/test/com/sun/servicetag/newer-registry-version.xml @@ -20,7 +20,7 @@ urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 Java Platform Standard Edition 6 (Java SE 6) id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -Sun Microsystems +Oracle Corporation sparc 2007-11-13 00:49:01 GMT global diff --git a/jdk/test/com/sun/servicetag/registration.xml b/jdk/test/com/sun/servicetag/registration.xml index e7a431a0f0f..287590ab153 100644 --- a/jdk/test/com/sun/servicetag/registration.xml +++ b/jdk/test/com/sun/servicetag/registration.xml @@ -7,8 +7,8 @@ 5.10 sparc Sun-Fire-V440 -Sun Microsystems -Sun Microsystems +Oracle Corporation +Oracle Corporation BEL078932 @@ -20,7 +20,7 @@ urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 Java Platform Standard Edition 6 (Java SE 6) id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -Sun Microsystems +Oracle Corporation sparc 2007-11-13 00:49:01 GMT global @@ -35,7 +35,7 @@ urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 Java Platform Standard Edition 6 (Java SE 6) id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586 -Sun Microsystems +Oracle Corporation i386 2007-11-13 00:49:01 GMT global @@ -50,7 +50,7 @@ urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92 Solaris Operating System -Sun Microsystems +Oracle Corporation sparc 2007-11-13 00:49:01 GMT global diff --git a/jdk/test/com/sun/servicetag/servicetag1.properties b/jdk/test/com/sun/servicetag/servicetag1.properties index 3a1e8acc352..c37bc365231 100644 --- a/jdk/test/com/sun/servicetag/servicetag1.properties +++ b/jdk/test/com/sun/servicetag/servicetag1.properties @@ -5,7 +5,7 @@ product_urn=urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 product_parent=Java Platform Standard Edition 6 (Java SE 6) product_defined_inst_id=id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -product_vendor=Sun Microsystems +product_vendor=Oracle Corporation platform_arch=sparc timestamp=2007-11-12 05:19:40 GMT container=global diff --git a/jdk/test/com/sun/servicetag/servicetag2.properties b/jdk/test/com/sun/servicetag/servicetag2.properties index d5dbe14f8f1..54867f7a6b0 100644 --- a/jdk/test/com/sun/servicetag/servicetag2.properties +++ b/jdk/test/com/sun/servicetag/servicetag2.properties @@ -5,7 +5,7 @@ product_urn=urn:uuid:b58ef9a8-5ae8-11db-a023-080020a9ed93 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 product_parent=Java Platform Standard Edition 6 (Java SE 6) product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586 -product_vendor=Sun Microsystems +product_vendor=Oracle Corporation platform_arch=i386 timestamp=2007-11-12 06:12:21 GMT container=global diff --git a/jdk/test/com/sun/servicetag/servicetag3.properties b/jdk/test/com/sun/servicetag/servicetag3.properties index 6ca5dc79d97..5bd4e477843 100644 --- a/jdk/test/com/sun/servicetag/servicetag3.properties +++ b/jdk/test/com/sun/servicetag/servicetag3.properties @@ -5,7 +5,7 @@ product_urn=urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113 product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92 product_parent=Solaris Operating System product_defined_inst_id= -product_vendor=Sun Microsystems +product_vendor=Oracle Corporation platform_arch=sparc timestamp=2007-06-20 22:07:11 GMT container=global diff --git a/jdk/test/com/sun/servicetag/servicetag4.properties b/jdk/test/com/sun/servicetag/servicetag4.properties index ba7c3c526e7..02892041f5a 100644 --- a/jdk/test/com/sun/servicetag/servicetag4.properties +++ b/jdk/test/com/sun/servicetag/servicetag4.properties @@ -5,7 +5,7 @@ product_urn=urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 product_parent=Java Platform Standard Edition 6 (Java SE 6) product_defined_inst_id=id=1.6.0_05-b01 amd64,dir=/myjdk/linux-amd64 -product_vendor=Sun Microsystems +product_vendor=Oracle Corporation platform_arch=x64 timestamp=2007-12-12 05:19:40 GMT container=global diff --git a/jdk/test/com/sun/servicetag/servicetag5.properties b/jdk/test/com/sun/servicetag/servicetag5.properties index 84e44c3243d..f7e53bfc0e0 100644 --- a/jdk/test/com/sun/servicetag/servicetag5.properties +++ b/jdk/test/com/sun/servicetag/servicetag5.properties @@ -5,7 +5,7 @@ product_urn=urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 product_parent=Java Platform Standard Edition 6 (Java SE 6) product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre -product_vendor=Sun Microsystems +product_vendor=Oracle Corporation platform_arch=x86 timestamp=2007-11-29 17:59:42 GMT container=global From 84ca32b8df792c3b5bea6c60c49a58f1b08cc468 Mon Sep 17 00:00:00 2001 From: Yoshito Umaoka Date: Thu, 23 Sep 2010 20:05:20 -0700 Subject: [PATCH 29/88] 6986612: pit jdk7 b112: java.util.Locale getDisplayVariant() sqe test getDisplayVariantTests.java fails Reviewed-by: dougfelt --- jdk/src/share/classes/java/util/Locale.java | 3 +++ .../share/classes/sun/util/locale/BaseLocale.java | 14 ++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/java/util/Locale.java b/jdk/src/share/classes/java/util/Locale.java index 49b85866ed3..1043c8792c4 100644 --- a/jdk/src/share/classes/java/util/Locale.java +++ b/jdk/src/share/classes/java/util/Locale.java @@ -569,6 +569,9 @@ public final class Locale implements Cloneable, Serializable { * @exception NullPointerException thrown if any argument is null. */ public Locale(String language, String country, String variant) { + if (language== null || country == null || variant == null) { + throw new NullPointerException(); + } _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant); _extensions = getCompatibilityExtensions(language, "", country, variant); } diff --git a/jdk/src/share/classes/sun/util/locale/BaseLocale.java b/jdk/src/share/classes/sun/util/locale/BaseLocale.java index a3314826f6b..2137dbd8691 100644 --- a/jdk/src/share/classes/sun/util/locale/BaseLocale.java +++ b/jdk/src/share/classes/sun/util/locale/BaseLocale.java @@ -64,12 +64,14 @@ public final class BaseLocale { public static BaseLocale getInstance(String language, String script, String region, String variant) { // JDK uses deprecated ISO639.1 language codes for he, yi and id - if (AsciiUtil.caseIgnoreMatch(language, "he")) { - language = "iw"; - } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { - language = "ji"; - } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { - language = "in"; + if (language != null) { + if (AsciiUtil.caseIgnoreMatch(language, "he")) { + language = "iw"; + } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { + language = "ji"; + } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { + language = "in"; + } } Key key = new Key(language, script, region, variant); From e0c099ccb235f0b0fdc7834c3db2b6f691295bfc Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 24 Sep 2010 14:03:33 -0700 Subject: [PATCH 30/88] 6987114: Fix top level "test" Makefile logic, add jdk/make/Makefile test target Reviewed-by: mchung --- Makefile | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 065e0c55edc..d42650e58ce 100644 --- a/Makefile +++ b/Makefile @@ -558,9 +558,12 @@ endif # rule to test ################################################################ -.NOTPARALLEL: test +.NOTPARALLEL: test_run -test: test_clean test_start test_summary +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary test_start: @$(ECHO) "Tests started at `$(DATE)`" @@ -586,7 +589,7 @@ test_summary: $(OUTPUTDIR)/test_failures.txt # Get failure list from log $(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt @$(RM) $@ - @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) > $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ # Get log file of all tests run JDK_TO_TEST := $(shell \ @@ -598,10 +601,11 @@ JDK_TO_TEST := $(shell \ $(ECHO) "$(PRODUCT_HOME)"; \ fi \ ) +TEST_TARGETS=all $(OUTPUTDIR)/test_log.txt: $(RM) $@ - ( $(CD) test && \ - $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) \ + ( $(CD) test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ ) | tee $@ ################################################################ @@ -614,7 +618,7 @@ include ./make/jprt.gmk # PHONY ################################################################ -.PHONY: all test test_start test_summary test_clean \ +.PHONY: all test test_run test_start test_summary test_clean \ generic_build_repo_series \ what clobber insane \ dev dev-build dev-sanity dev-clobber \ From 4e0aea2b650309910a4adea82558a1ce2df95184 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 24 Sep 2010 14:04:01 -0700 Subject: [PATCH 31/88] 6987117: Add jprt test sets Reviewed-by: mchung --- make/jprt.properties | 333 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 297 insertions(+), 36 deletions(-) diff --git a/make/jprt.properties b/make/jprt.properties index 6a4541d0ab6..777e27c8a2f 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -25,49 +25,310 @@ # Properties for jprt -# Use whatever release that the submitted job requests +# At submit time, the release supplied will be in jprt.submit.release +# and will be one of the official release names defined in jprt. +# jprt supports property value expansion using ${property.name} syntax. + +# This tells jprt what default release we want to build jprt.tools.default.release=${jprt.submit.release} # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug -# Shortened list of vm tests -jprt.test.targets= \ - *-product-*-jvm98, \ - *-product-*-scimark, \ - *-product-*-runThese, \ - *-product-*-GCBasher_default, \ - *-product-*-GCOld_default, \ - *-product-*-jbb_default +# Define the Windows we want (temporary) +jprt.my.windows.i586.jdk7b107=windows_i586_5.0 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0 +jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} -# Test targets in test/Makefile -jprt.make.rule.test.targets= \ - *-product-*-langtools_jtreg, \ - *-product-*-jdk_beans1, \ - *-product-*-jdk_beans2, \ - *-product-*-jdk_beans3, \ - *-product-*-jdk_io, \ - *-product-*-jdk_lang, \ - *-product-*-jdk_management1, \ - *-product-*-jdk_management2, \ - *-product-*-jdk_math, \ - *-product-*-jdk_misc, \ - *-product-*-jdk_net, \ - *-product-*-jdk_nio1, \ - *-product-*-jdk_nio2, \ - *-product-*-jdk_nio3, \ - *-product-*-jdk_security1, \ - *-product-*-jdk_security2, \ - *-product-*-jdk_security3, \ - *-product-*-jdk_text, \ - *-product-*-jdk_tools1, \ - *-product-*-jdk_tools2, \ - *-product-*-jdk_util +# Standard list of jprt build targets for this source tree +jprt.build.targets= \ + solaris_sparc_5.10-{product|fastdebug}, \ + solaris_sparcv9_5.10-{product|fastdebug}, \ + solaris_i586_5.10-{product|fastdebug}, \ + solaris_x64_5.10-{product|fastdebug}, \ + linux_i586_2.6-{product|fastdebug}, \ + linux_x64_2.6-{product|fastdebug}, \ + ${jprt.my.windows.i586}-{product|fastdebug}, \ + windows_x64_5.2-{product|fastdebug} -# Not Ready Yet: -# *-product-*-jdk_awt -# *-product-*-jdk_rmi -# *-product-*-jdk_swing +# User can select the test set with jprt submit "-testset name" option +jprt.my.test.set=${jprt.test.set} + +# Default vm test targets (no fastdebug & limited c2 testing) +jprt.vm.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-jvm98, \ + solaris_sparcv9_5.10-product-c2-jvm98, \ + solaris_i586_5.10-product-c1-jvm98, \ + solaris_x64_5.10-product-c2-jvm98, \ + linux_i586_2.6-product-{c1|c2}-jvm98, \ + linux_x64_2.6-product-c2-jvm98, \ + ${jprt.my.windows.i586}-product-c1-jvm98, \ + windows_x64_5.2-product-c2-jvm98, \ + \ + solaris_sparc_5.10-product-c1-scimark, \ + solaris_sparcv9_5.10-product-c2-scimark, \ + solaris_i586_5.10-product-c1-scimark, \ + solaris_x64_5.10-product-c2-scimark, \ + linux_i586_2.6-product-{c1|c2}-scimark, \ + linux_x64_2.6-product-c2-scimark, \ + ${jprt.my.windows.i586}-product-c1-scimark, \ + windows_x64_5.2-product-c2-scimark + +# Default jdk test targets in test/Makefile (no fastdebug & limited c2 testing) +jprt.make.rule.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-langtools_jtreg, \ + solaris_sparcv9_5.10-product-c2-langtools_jtreg, \ + solaris_i586_5.10-product-c1-langtools_jtreg, \ + solaris_x64_5.10-product-c2-langtools_jtreg, \ + linux_i586_2.6-product-{c1|c2}-langtools_jtreg, \ + linux_x64_2.6-product-c2-langtools_jtreg, \ + ${jprt.my.windows.i586}-product-c1-langtools_jtreg, \ + windows_x64_5.2-product-c2-langtools_jtreg, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans1, \ + solaris_sparcv9_5.10-product-c2-jdk_beans1, \ + solaris_i586_5.10-product-c1-jdk_beans1, \ + solaris_x64_5.10-product-c2-jdk_beans1, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ + linux_x64_2.6-product-c2-jdk_beans1, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \ + windows_x64_5.2-product-c2-jdk_beans1, \ + \ + solaris_sparc_5.10-product-c1-jdk_io, \ + solaris_sparcv9_5.10-product-c2-jdk_io, \ + solaris_i586_5.10-product-c1-jdk_io, \ + solaris_x64_5.10-product-c2-jdk_io, \ + linux_i586_2.6-product-{c1|c2}-jdk_io, \ + linux_x64_2.6-product-c2-jdk_io, \ + ${jprt.my.windows.i586}-product-c1-jdk_io, \ + windows_x64_5.2-product-c2-jdk_io, \ + \ + solaris_sparc_5.10-product-c1-jdk_lang, \ + solaris_sparcv9_5.10-product-c2-jdk_lang, \ + solaris_i586_5.10-product-c1-jdk_lang, \ + solaris_x64_5.10-product-c2-jdk_lang, \ + linux_i586_2.6-product-{c1|c2}-jdk_lang, \ + linux_x64_2.6-product-c2-jdk_lang, \ + ${jprt.my.windows.i586}-product-c1-jdk_lang, \ + windows_x64_5.2-product-c2-jdk_lang, \ + \ + solaris_sparc_5.10-product-c1-jdk_math, \ + solaris_sparcv9_5.10-product-c2-jdk_math, \ + solaris_i586_5.10-product-c1-jdk_math, \ + solaris_x64_5.10-product-c2-jdk_math, \ + linux_i586_2.6-product-{c1|c2}-jdk_math, \ + linux_x64_2.6-product-c2-jdk_math, \ + ${jprt.my.windows.i586}-product-c1-jdk_math, \ + windows_x64_5.2-product-c2-jdk_math, \ + \ + solaris_sparc_5.10-product-c1-jdk_misc, \ + solaris_sparcv9_5.10-product-c2-jdk_misc, \ + solaris_i586_5.10-product-c1-jdk_misc, \ + solaris_x64_5.10-product-c2-jdk_misc, \ + linux_i586_2.6-product-{c1|c2}-jdk_misc, \ + linux_x64_2.6-product-c2-jdk_misc, \ + ${jprt.my.windows.i586}-product-c1-jdk_misc, \ + windows_x64_5.2-product-c2-jdk_misc, \ + \ + solaris_sparc_5.10-product-c1-jdk_net, \ + solaris_sparcv9_5.10-product-c2-jdk_net, \ + solaris_i586_5.10-product-c1-jdk_net, \ + solaris_x64_5.10-product-c2-jdk_net, \ + linux_i586_2.6-product-{c1|c2}-jdk_net, \ + linux_x64_2.6-product-c2-jdk_net, \ + ${jprt.my.windows.i586}-product-c1-jdk_net, \ + windows_x64_5.2-product-c2-jdk_net, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio1, \ + solaris_sparcv9_5.10-product-c2-jdk_nio1, \ + solaris_i586_5.10-product-c1-jdk_nio1, \ + solaris_x64_5.10-product-c2-jdk_nio1, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ + linux_x64_2.6-product-c2-jdk_nio1, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \ + windows_x64_5.2-product-c2-jdk_nio1, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio2, \ + solaris_sparcv9_5.10-product-c2-jdk_nio2, \ + solaris_i586_5.10-product-c1-jdk_nio2, \ + solaris_x64_5.10-product-c2-jdk_nio2, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ + linux_x64_2.6-product-c2-jdk_nio2, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \ + windows_x64_5.2-product-c2-jdk_nio2, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio3, \ + solaris_sparcv9_5.10-product-c2-jdk_nio3, \ + solaris_i586_5.10-product-c1-jdk_nio3, \ + solaris_x64_5.10-product-c2-jdk_nio3, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ + linux_x64_2.6-product-c2-jdk_nio3, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \ + windows_x64_5.2-product-c2-jdk_nio3, \ + \ + solaris_sparc_5.10-product-c1-jdk_security1, \ + solaris_sparcv9_5.10-product-c2-jdk_security1, \ + solaris_i586_5.10-product-c1-jdk_security1, \ + solaris_x64_5.10-product-c2-jdk_security1, \ + linux_i586_2.6-product-{c1|c2}-jdk_security1, \ + linux_x64_2.6-product-c2-jdk_security1, \ + ${jprt.my.windows.i586}-product-c1-jdk_security1, \ + windows_x64_5.2-product-c2-jdk_security1, \ + \ + solaris_sparc_5.10-product-c1-jdk_text, \ + solaris_sparcv9_5.10-product-c2-jdk_text, \ + solaris_i586_5.10-product-c1-jdk_text, \ + solaris_x64_5.10-product-c2-jdk_text, \ + linux_i586_2.6-product-{c1|c2}-jdk_text, \ + linux_x64_2.6-product-c2-jdk_text, \ + ${jprt.my.windows.i586}-product-c1-jdk_text, \ + windows_x64_5.2-product-c2-jdk_text, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools1, \ + solaris_sparcv9_5.10-product-c2-jdk_tools1, \ + solaris_i586_5.10-product-c1-jdk_tools1, \ + solaris_x64_5.10-product-c2-jdk_tools1, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ + linux_x64_2.6-product-c2-jdk_tools1, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \ + windows_x64_5.2-product-c2-jdk_tools1, \ + \ + solaris_sparc_5.10-product-c1-jdk_util, \ + solaris_sparcv9_5.10-product-c2-jdk_util, \ + solaris_i586_5.10-product-c1-jdk_util, \ + solaris_x64_5.10-product-c2-jdk_util, \ + linux_i586_2.6-product-{c1|c2}-jdk_util, \ + linux_x64_2.6-product-c2-jdk_util, \ + ${jprt.my.windows.i586}-product-c1-jdk_util, \ + windows_x64_5.2-product-c2-jdk_util + +# All vm test targets (but still no fastdebug & limited c2 testing) +jprt.vm.all.test.targets= \ + \ + ${jprt.vm.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-runThese, \ + solaris_sparcv9_5.10-product-c2-runThese, \ + solaris_i586_5.10-product-c1-runThese, \ + solaris_x64_5.10-product-c2-runThese, \ + linux_i586_2.6-product-{c1|c2}-runThese, \ + linux_x64_2.6-product-c2-runThese, \ + ${jprt.my.windows.i586}-product-c1-runThese, \ + windows_x64_5.2-product-c2-runThese, \ + \ + solaris_sparc_5.10-product-c1-jbb_default, \ + solaris_sparcv9_5.10-product-c2-jbb_default, \ + solaris_i586_5.10-product-c1-jbb_default, \ + solaris_x64_5.10-product-c2-jbb_default, \ + linux_i586_2.6-product-{c1|c2}-jbb_default, \ + linux_x64_2.6-product-c2-jbb_default, \ + ${jprt.my.windows.i586}-product-c1-jbb_default, \ + windows_x64_5.2-product-c2-jbb_default + +# All jdk test targets (but still no fastdebug & limited c2 testing) +jprt.make.rule.all.test.targets= \ + \ + ${jprt.make.rule.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-jdk_awt, \ + solaris_sparcv9_5.10-product-c2-jdk_awt, \ + solaris_i586_5.10-product-c1-jdk_awt, \ + solaris_x64_5.10-product-c2-jdk_awt, \ + linux_i586_2.6-product-{c1|c2}-jdk_awt, \ + linux_x64_2.6-product-c2-jdk_awt, \ + ${jprt.my.windows.i586}-product-c1-jdk_awt, \ + windows_x64_5.2-product-c2-jdk_awt, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans2, \ + solaris_sparcv9_5.10-product-c2-jdk_beans2, \ + solaris_i586_5.10-product-c1-jdk_beans2, \ + solaris_x64_5.10-product-c2-jdk_beans2, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ + linux_x64_2.6-product-c2-jdk_beans2, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \ + windows_x64_5.2-product-c2-jdk_beans2, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans3, \ + solaris_sparcv9_5.10-product-c2-jdk_beans3, \ + solaris_i586_5.10-product-c1-jdk_beans3, \ + solaris_x64_5.10-product-c2-jdk_beans3, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ + linux_x64_2.6-product-c2-jdk_beans3, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \ + windows_x64_5.2-product-c2-jdk_beans3, \ + \ + solaris_sparc_5.10-product-c1-jdk_management1, \ + solaris_sparcv9_5.10-product-c2-jdk_management1, \ + solaris_i586_5.10-product-c1-jdk_management1, \ + solaris_x64_5.10-product-c2-jdk_management1, \ + linux_i586_2.6-product-{c1|c2}-jdk_management1, \ + linux_x64_2.6-product-c2-jdk_management1, \ + ${jprt.my.windows.i586}-product-c1-jdk_management1, \ + windows_x64_5.2-product-c2-jdk_management1, \ + \ + solaris_sparc_5.10-product-c1-jdk_management2, \ + solaris_sparcv9_5.10-product-c2-jdk_management2, \ + solaris_i586_5.10-product-c1-jdk_management2, \ + solaris_x64_5.10-product-c2-jdk_management2, \ + linux_i586_2.6-product-{c1|c2}-jdk_management2, \ + linux_x64_2.6-product-c2-jdk_management2, \ + ${jprt.my.windows.i586}-product-c1-jdk_management2, \ + windows_x64_5.2-product-c2-jdk_management2, \ + \ + solaris_sparc_5.10-product-c1-jdk_rmi, \ + solaris_sparcv9_5.10-product-c2-jdk_rmi, \ + solaris_i586_5.10-product-c1-jdk_rmi, \ + solaris_x64_5.10-product-c2-jdk_rmi, \ + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ + linux_x64_2.6-product-c2-jdk_rmi, \ + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \ + windows_x64_5.2-product-c2-jdk_rmi, \ + \ + solaris_sparc_5.10-product-c1-jdk_security2, \ + solaris_sparcv9_5.10-product-c2-jdk_security2, \ + solaris_i586_5.10-product-c1-jdk_security2, \ + solaris_x64_5.10-product-c2-jdk_security2, \ + linux_i586_2.6-product-{c1|c2}-jdk_security2, \ + linux_x64_2.6-product-c2-jdk_security2, \ + ${jprt.my.windows.i586}-product-c1-jdk_security2, \ + windows_x64_5.2-product-c2-jdk_security2, \ + \ + solaris_sparc_5.10-product-c1-jdk_security3, \ + solaris_sparcv9_5.10-product-c2-jdk_security3, \ + solaris_i586_5.10-product-c1-jdk_security3, \ + solaris_x64_5.10-product-c2-jdk_security3, \ + linux_i586_2.6-product-{c1|c2}-jdk_security3, \ + linux_x64_2.6-product-c2-jdk_security3, \ + ${jprt.my.windows.i586}-product-c1-jdk_security3, \ + windows_x64_5.2-product-c2-jdk_security3, \ + \ + solaris_sparc_5.10-product-c1-jdk_swing, \ + solaris_sparcv9_5.10-product-c2-jdk_swing, \ + solaris_i586_5.10-product-c1-jdk_swing, \ + solaris_x64_5.10-product-c2-jdk_swing, \ + linux_i586_2.6-product-{c1|c2}-jdk_swing, \ + linux_x64_2.6-product-c2-jdk_swing, \ + ${jprt.my.windows.i586}-product-c1-jdk_swing, \ + windows_x64_5.2-product-c2-jdk_swing, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools2, \ + solaris_sparcv9_5.10-product-c2-jdk_tools2, \ + solaris_i586_5.10-product-c1-jdk_tools2, \ + solaris_x64_5.10-product-c2-jdk_tools2, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ + linux_x64_2.6-product-c2-jdk_tools2, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \ + windows_x64_5.2-product-c2-jdk_tools2 + +# Select list to use (allow for testset to be empty too) +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} +jprt.vm..test.targets=${jprt.vm.default.test.targets} +jprt.vm.test.targets=${jprt.vm.${jprt.my.test.set}.test.targets} +jprt.test.targets=${jprt.vm.test.targets} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev From 02949194028449ac81a6da92dfe1aca140ee7966 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 24 Sep 2010 14:06:57 -0700 Subject: [PATCH 32/88] 6987117: Add jprt test sets Reviewed-by: mchung --- jdk/make/jprt.properties | 282 ++++++++++++++++++++++++++++++++++----- 1 file changed, 252 insertions(+), 30 deletions(-) diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties index 4ae844da4a2..6c725c39930 100644 --- a/jdk/make/jprt.properties +++ b/jdk/make/jprt.properties @@ -25,43 +25,265 @@ # Properties for jprt -# Use whatever release that the submitted job requests +# At submit time, the release supplied will be in jprt.submit.release +# and will be one of the official release names defined in jprt. +# jprt supports property value expansion using ${property.name} syntax. + +# This tells jprt what default release we want to build jprt.tools.default.release=${jprt.submit.release} # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug -# Standard test target for everybody -jprt.test.targets=*-*-*-jvm98 +# Define the Windows we want (temporary) +jprt.my.windows.i586.jdk7b107=windows_i586_5.0 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0 +jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} -# Test targets in test/Makefile (some longer running tests only test c2) -jprt.make.rule.test.targets= \ - *-product-*-jdk_beans1, \ - *-product-*-jdk_beans2, \ - *-product-*-jdk_beans3, \ - *-product-*-jdk_io, \ - *-product-*-jdk_lang, \ - *-product-*-jdk_management1, \ - *-product-*-jdk_management2, \ - *-product-*-jdk_math, \ - *-product-*-jdk_misc, \ - *-product-*-jdk_net, \ - *-product-*-jdk_nio1, \ - *-product-*-jdk_nio2, \ - *-product-*-jdk_nio3, \ - *-product-*-jdk_security1, \ - *-product-*-jdk_security2, \ - *-product-*-jdk_security3, \ - *-product-*-jdk_text, \ - *-product-*-jdk_tools1, \ - *-product-*-jdk_tools2, \ - *-product-*-jdk_util +# Standard list of jprt build targets for this source tree +jprt.build.targets= \ + solaris_sparc_5.10-{product|fastdebug}, \ + solaris_sparcv9_5.10-{product|fastdebug}, \ + solaris_i586_5.10-{product|fastdebug}, \ + solaris_x64_5.10-{product|fastdebug}, \ + linux_i586_2.6-{product|fastdebug}, \ + linux_x64_2.6-{product|fastdebug}, \ + ${jprt.my.windows.i586}-{product|fastdebug}, \ + windows_x64_5.2-{product|fastdebug} -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch -jprt2.make.rule.test.targets= \ - *-product-*-jdk_awt, \ - *-product-*-jdk_rmi, \ - *-product-*-jdk_swing, \ +# Standard vm test target +jprt.test.targets= \ + solaris_sparc_5.10-product-c1-jvm98, \ + solaris_sparcv9_5.10-product-c2-jvm98, \ + solaris_i586_5.10-product-c1-jvm98, \ + solaris_x64_5.10-product-c2-jvm98, \ + linux_i586_2.6-product-{c1|c2}-jvm98, \ + linux_x64_2.6-product-c2-jvm98, \ + ${jprt.my.windows.i586}-product-c1-jvm98, \ + windows_x64_5.2-product-c2-jvm98 + +# User can select the test set with jprt submit "-testset name" option +jprt.my.test.set=${jprt.test.set} + +# Default jdk test targets in test/Makefile (no fastdebug & limited c2) +jprt.make.rule.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-jdk_beans1, \ + solaris_sparcv9_5.10-product-c2-jdk_beans1, \ + solaris_i586_5.10-product-c1-jdk_beans1, \ + solaris_x64_5.10-product-c2-jdk_beans1, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ + linux_x64_2.6-product-c2-jdk_beans1, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \ + windows_x64_5.2-product-c2-jdk_beans1, \ + \ + solaris_sparc_5.10-product-c1-jdk_io, \ + solaris_sparcv9_5.10-product-c2-jdk_io, \ + solaris_i586_5.10-product-c1-jdk_io, \ + solaris_x64_5.10-product-c2-jdk_io, \ + linux_i586_2.6-product-{c1|c2}-jdk_io, \ + linux_x64_2.6-product-c2-jdk_io, \ + ${jprt.my.windows.i586}-product-c1-jdk_io, \ + windows_x64_5.2-product-c2-jdk_io, \ + \ + solaris_sparc_5.10-product-c1-jdk_lang, \ + solaris_sparcv9_5.10-product-c2-jdk_lang, \ + solaris_i586_5.10-product-c1-jdk_lang, \ + solaris_x64_5.10-product-c2-jdk_lang, \ + linux_i586_2.6-product-{c1|c2}-jdk_lang, \ + linux_x64_2.6-product-c2-jdk_lang, \ + ${jprt.my.windows.i586}-product-c1-jdk_lang, \ + windows_x64_5.2-product-c2-jdk_lang, \ + \ + solaris_sparc_5.10-product-c1-jdk_math, \ + solaris_sparcv9_5.10-product-c2-jdk_math, \ + solaris_i586_5.10-product-c1-jdk_math, \ + solaris_x64_5.10-product-c2-jdk_math, \ + linux_i586_2.6-product-{c1|c2}-jdk_math, \ + linux_x64_2.6-product-c2-jdk_math, \ + ${jprt.my.windows.i586}-product-c1-jdk_math, \ + windows_x64_5.2-product-c2-jdk_math, \ + \ + solaris_sparc_5.10-product-c1-jdk_misc, \ + solaris_sparcv9_5.10-product-c2-jdk_misc, \ + solaris_i586_5.10-product-c1-jdk_misc, \ + solaris_x64_5.10-product-c2-jdk_misc, \ + linux_i586_2.6-product-{c1|c2}-jdk_misc, \ + linux_x64_2.6-product-c2-jdk_misc, \ + ${jprt.my.windows.i586}-product-c1-jdk_misc, \ + windows_x64_5.2-product-c2-jdk_misc, \ + \ + solaris_sparc_5.10-product-c1-jdk_net, \ + solaris_sparcv9_5.10-product-c2-jdk_net, \ + solaris_i586_5.10-product-c1-jdk_net, \ + solaris_x64_5.10-product-c2-jdk_net, \ + linux_i586_2.6-product-{c1|c2}-jdk_net, \ + linux_x64_2.6-product-c2-jdk_net, \ + ${jprt.my.windows.i586}-product-c1-jdk_net, \ + windows_x64_5.2-product-c2-jdk_net, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio1, \ + solaris_sparcv9_5.10-product-c2-jdk_nio1, \ + solaris_i586_5.10-product-c1-jdk_nio1, \ + solaris_x64_5.10-product-c2-jdk_nio1, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ + linux_x64_2.6-product-c2-jdk_nio1, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \ + windows_x64_5.2-product-c2-jdk_nio1, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio2, \ + solaris_sparcv9_5.10-product-c2-jdk_nio2, \ + solaris_i586_5.10-product-c1-jdk_nio2, \ + solaris_x64_5.10-product-c2-jdk_nio2, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ + linux_x64_2.6-product-c2-jdk_nio2, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \ + windows_x64_5.2-product-c2-jdk_nio2, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio3, \ + solaris_sparcv9_5.10-product-c2-jdk_nio3, \ + solaris_i586_5.10-product-c1-jdk_nio3, \ + solaris_x64_5.10-product-c2-jdk_nio3, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ + linux_x64_2.6-product-c2-jdk_nio3, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \ + windows_x64_5.2-product-c2-jdk_nio3, \ + \ + solaris_sparc_5.10-product-c1-jdk_security1, \ + solaris_sparcv9_5.10-product-c2-jdk_security1, \ + solaris_i586_5.10-product-c1-jdk_security1, \ + solaris_x64_5.10-product-c2-jdk_security1, \ + linux_i586_2.6-product-{c1|c2}-jdk_security1, \ + linux_x64_2.6-product-c2-jdk_security1, \ + ${jprt.my.windows.i586}-product-c1-jdk_security1, \ + windows_x64_5.2-product-c2-jdk_security1, \ + \ + solaris_sparc_5.10-product-c1-jdk_text, \ + solaris_sparcv9_5.10-product-c2-jdk_text, \ + solaris_i586_5.10-product-c1-jdk_text, \ + solaris_x64_5.10-product-c2-jdk_text, \ + linux_i586_2.6-product-{c1|c2}-jdk_text, \ + linux_x64_2.6-product-c2-jdk_text, \ + ${jprt.my.windows.i586}-product-c1-jdk_text, \ + windows_x64_5.2-product-c2-jdk_text, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools1, \ + solaris_sparcv9_5.10-product-c2-jdk_tools1, \ + solaris_i586_5.10-product-c1-jdk_tools1, \ + solaris_x64_5.10-product-c2-jdk_tools1, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ + linux_x64_2.6-product-c2-jdk_tools1, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \ + windows_x64_5.2-product-c2-jdk_tools1, \ + \ + solaris_sparc_5.10-product-c1-jdk_util, \ + solaris_sparcv9_5.10-product-c2-jdk_util, \ + solaris_i586_5.10-product-c1-jdk_util, \ + solaris_x64_5.10-product-c2-jdk_util, \ + linux_i586_2.6-product-{c1|c2}-jdk_util, \ + linux_x64_2.6-product-c2-jdk_util, \ + ${jprt.my.windows.i586}-product-c1-jdk_util, \ + windows_x64_5.2-product-c2-jdk_util + +# All jdk test targets in test/Makefile (still no fastdebug & limited c2) +jprt.make.rule.all.test.targets= \ + \ + ${jprt.make.rule.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-jdk_awt, \ + solaris_sparcv9_5.10-product-c2-jdk_awt, \ + solaris_i586_5.10-product-c1-jdk_awt, \ + solaris_x64_5.10-product-c2-jdk_awt, \ + linux_i586_2.6-product-{c1|c2}-jdk_awt, \ + linux_x64_2.6-product-c2-jdk_awt, \ + ${jprt.my.windows.i586}-product-c1-jdk_awt, \ + windows_x64_5.2-product-c2-jdk_awt, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans2, \ + solaris_sparcv9_5.10-product-c2-jdk_beans2, \ + solaris_i586_5.10-product-c1-jdk_beans2, \ + solaris_x64_5.10-product-c2-jdk_beans2, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ + linux_x64_2.6-product-c2-jdk_beans2, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \ + windows_x64_5.2-product-c2-jdk_beans2, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans3, \ + solaris_sparcv9_5.10-product-c2-jdk_beans3, \ + solaris_i586_5.10-product-c1-jdk_beans3, \ + solaris_x64_5.10-product-c2-jdk_beans3, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ + linux_x64_2.6-product-c2-jdk_beans3, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \ + windows_x64_5.2-product-c2-jdk_beans3, \ + \ + solaris_sparc_5.10-product-c1-jdk_management1, \ + solaris_sparcv9_5.10-product-c2-jdk_management1, \ + solaris_i586_5.10-product-c1-jdk_management1, \ + solaris_x64_5.10-product-c2-jdk_management1, \ + linux_i586_2.6-product-{c1|c2}-jdk_management1, \ + linux_x64_2.6-product-c2-jdk_management1, \ + ${jprt.my.windows.i586}-product-c1-jdk_management1, \ + windows_x64_5.2-product-c2-jdk_management1, \ + \ + solaris_sparc_5.10-product-c1-jdk_management2, \ + solaris_sparcv9_5.10-product-c2-jdk_management2, \ + solaris_i586_5.10-product-c1-jdk_management2, \ + solaris_x64_5.10-product-c2-jdk_management2, \ + linux_i586_2.6-product-{c1|c2}-jdk_management2, \ + linux_x64_2.6-product-c2-jdk_management2, \ + ${jprt.my.windows.i586}-product-c1-jdk_management2, \ + windows_x64_5.2-product-c2-jdk_management2, \ + \ + solaris_sparc_5.10-product-c1-jdk_rmi, \ + solaris_sparcv9_5.10-product-c2-jdk_rmi, \ + solaris_i586_5.10-product-c1-jdk_rmi, \ + solaris_x64_5.10-product-c2-jdk_rmi, \ + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ + linux_x64_2.6-product-c2-jdk_rmi, \ + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \ + windows_x64_5.2-product-c2-jdk_rmi, \ + \ + solaris_sparc_5.10-product-c1-jdk_security2, \ + solaris_sparcv9_5.10-product-c2-jdk_security2, \ + solaris_i586_5.10-product-c1-jdk_security2, \ + solaris_x64_5.10-product-c2-jdk_security2, \ + linux_i586_2.6-product-{c1|c2}-jdk_security2, \ + linux_x64_2.6-product-c2-jdk_security2, \ + ${jprt.my.windows.i586}-product-c1-jdk_security2, \ + windows_x64_5.2-product-c2-jdk_security2, \ + \ + solaris_sparc_5.10-product-c1-jdk_security3, \ + solaris_sparcv9_5.10-product-c2-jdk_security3, \ + solaris_i586_5.10-product-c1-jdk_security3, \ + solaris_x64_5.10-product-c2-jdk_security3, \ + linux_i586_2.6-product-{c1|c2}-jdk_security3, \ + linux_x64_2.6-product-c2-jdk_security3, \ + ${jprt.my.windows.i586}-product-c1-jdk_security3, \ + windows_x64_5.2-product-c2-jdk_security3, \ + \ + solaris_sparc_5.10-product-c1-jdk_swing, \ + solaris_sparcv9_5.10-product-c2-jdk_swing, \ + solaris_i586_5.10-product-c1-jdk_swing, \ + solaris_x64_5.10-product-c2-jdk_swing, \ + linux_i586_2.6-product-{c1|c2}-jdk_swing, \ + linux_x64_2.6-product-c2-jdk_swing, \ + ${jprt.my.windows.i586}-product-c1-jdk_swing, \ + windows_x64_5.2-product-c2-jdk_swing, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools2, \ + solaris_sparcv9_5.10-product-c2-jdk_tools2, \ + solaris_i586_5.10-product-c1-jdk_tools2, \ + solaris_x64_5.10-product-c2-jdk_tools2, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ + linux_x64_2.6-product-c2-jdk_tools2, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \ + windows_x64_5.2-product-c2-jdk_tools2 + +# Select list to use (allow for testset to be empty too) +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev From f181e2fb8f86e73192d02e12b303587797bfe2c9 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 24 Sep 2010 14:22:01 -0700 Subject: [PATCH 33/88] 6987114: Fix top level "test" Makefile logic, add jdk/make/Makefile test target 6987113: Remove SCCS logic from makefiles Reviewed-by: mchung --- jdk/make/Makefile | 76 ++++++++++++++++++++------- jdk/make/common/Cscope.gmk | 2 +- jdk/make/common/Defs.gmk | 34 +----------- jdk/make/common/Rules-SCCS.gmk | 70 ------------------------ jdk/make/common/shared/Defs-utils.gmk | 5 +- jdk/test/ProblemList.txt | 21 ++++++++ 6 files changed, 82 insertions(+), 126 deletions(-) delete mode 100644 jdk/make/common/Rules-SCCS.gmk diff --git a/jdk/make/Makefile b/jdk/make/Makefile index 61dbf827194..63e7803ffe3 100644 --- a/jdk/make/Makefile +++ b/jdk/make/Makefile @@ -75,7 +75,6 @@ import_product -- copy in the product components \n\ import_fastdebug -- copy in the fastdebug components \n\ import_debug -- copy in the debug components \n\ modules -- build the jdk and jre module images (experimental) \n\ -sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\ create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\ " @@ -278,21 +277,6 @@ include $(BUILDDIR)/common/Sanity.gmk $(OUTPUTDIR) $(TEMPDIR): $(MKDIR) -p $@ -# cleanup everything. If the workspace is not being built by the control -# workspace, and if it is a Teamware workspace, then see if there are -# any files which are not under SCCS control. -clean clobber:: -ifndef EXTERNALSANITYCONTROL - @if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \ - $(ECHO) '\nPerforming workspace scan for remnant files.\n' \ - ' Any files listed below are not under SCCS control in the workspace\n' \ - ' and you should review them and possibly remove them manually:' ; \ - $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \ - $(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \ - $(ECHO) 'End of workspace scan.' ; \ - fi -endif - # this should be the last rule in this file: all:: @if [ -r $(WARNING_FILE) ]; then \ @@ -341,16 +325,70 @@ endif include $(BUILDDIR)/common/internal/BinaryPlugs.gmk # -# Get top level sccs_get rule +# Test rule # -include $(BUILDDIR)/common/Rules-SCCS.gmk +.NOTPARALLEL: test_run + +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary + +test_start: + @$(ECHO) "Tests started at `$(DATE)`" + +test_clean: + $(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt + +test_summary: $(OUTPUTDIR)/test_failures.txt + @$(ECHO) "#################################################" + @$(ECHO) "Tests completed at `$(DATE)`" + @( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \ + || $(ECHO) "No TEST STATS seen in log" ) + @$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt" + @$(ECHO) "#################################################" + @if [ -s $< ] ; then \ + $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \ + $(CAT) $<; \ + exit 1; \ + else \ + $(ECHO) "Success! No failures detected"; \ + fi + +# Get failure list from log +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt + @$(RM) $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ + +# Get log file of all tests run +JDK_TO_TEST := $(shell \ + if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; \ + elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)"; \ + elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then \ + $(ECHO) "$(PRODUCT_HOME)"; \ + fi \ +) + +TEST_TARGETS=jdk_all +$(OUTPUTDIR)/test_log.txt: + $(RM) $@ + ( $(CD) ../test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ + ) | tee $@ + +# # JPRT rules +# + include jprt.gmk # # Phonies to avoid accidents. # .PHONY: all build clean clobber optimized debug fastdebug create_links \ - import import_product import_fastdebug import_debug + import import_product import_fastdebug import_debug \ + test test_run test_start test_clean test_summary diff --git a/jdk/make/common/Cscope.gmk b/jdk/make/common/Cscope.gmk index 7ec94fd1276..79da2fc9e30 100644 --- a/jdk/make/common/Cscope.gmk +++ b/jdk/make/common/Cscope.gmk @@ -76,7 +76,7 @@ cscope.out: cscope.files FRC # What files should we include? A simple rule might be just those files under # SCM control, however this would miss files we create like the opcodes and # CClassHeaders. The following attempts to find everything that is *useful*. -# (.del files are created by sccsrm, demo directories contain many .java files +# (demo directories contain many .java files # that probably aren't useful for development, and the pkgarchive may contain # duplicates of files within the source hierarchy). The ordering of the .raw # file is an attempt to make cscope display the most relevant files first. diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 8d3e0fd32c8..31e3a4a8f65 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -334,7 +334,7 @@ DOCSDIR = $(OUTPUTDIR)/docs$(DOCSDIRSUFFIX) DOCSDIRSUFFIX = # The MESSAGE, WARNING and ERROR files are used to store sanityck and -# SCCS check messages, warnings and errors. +# warnings and errors. ifndef ERROR_FILE ERROR_FILE = $(OUTPUTDIR)/sanityCheckErrors.txt endif @@ -634,38 +634,6 @@ LINTFLAGS = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \ VERSION_DEFINES = -DRELEASE='"$(RELEASE)"' -# Note: As a rule, GNU Make rules should not appear in any of the -# Defs*.gmk files. These were added for Kestrel-Solaris and do address -# a TeamWare bug. They should be moved elsewhere for Merlin. -# -# Override gnumake built-in rules which do sccs get operations badly. -# (They put the checked out code in the current directory, not in the -# directory of the original file.) -# Since this is a symptom of a teamware failure, complain and die on the spot. - -# This message immediately goes to stdout and the build terminates. -define SCCS-trouble -$(error \ -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \ - is out of date with respect to its SCCS file $<. \ - This can happen from an unresolved Teamware conflict, a file movement, or \ - a failure in which SCCS files are updated but the 'sccs get' was not done. \ - You should double check for other out of date files in your workspace. \ - Or run: cd $(TOPDIR) && $(MAKE) sccs_get") -endef - -%:: s.% - @$(SCCS-trouble) -%:: SCCS/s.% - @$(SCCS-trouble) - @$(ECHO) " is out of date with respect to its SCCS file." >> $(WARNING_FILE) - @$(ECHO) " This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE) - @$(ECHO) " This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE) - @$(ECHO) " in which SCCS files are updated but not checked out." >> $(WARNING_FILE) - @$(ECHO) " Check for other out of date files in your workspace." >> $(WARNING_FILE) - @$(ECHO) "" >> $(WARNING_FILE) - @#exit 666 - ifdef INSANE export INSANE endif diff --git a/jdk/make/common/Rules-SCCS.gmk b/jdk/make/common/Rules-SCCS.gmk deleted file mode 100644 index 7f75aca15b7..00000000000 --- a/jdk/make/common/Rules-SCCS.gmk +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code 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 -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# Only get these rules if SCCS is available -# - -ifdef SCCS - -# SCCS command to extract out latest source -SCCS_GET=$(SCCS) get -s - -# -# Make sure all files in workspace are fresh -# -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable - $(prep-target) - @$(CUT) -d' ' -f1 $< \ - | $(GREP) -v '^VERSION' \ - | $(GREP) -v '^deleted_files' \ - | $(GREP) -v '^Codemgr_wsdata' > $@ - -sccs_get: $(TEMP_ALL_FILES) - @$(PRINTF) "Workspace has %d files\n" `$(CAT) $< | $(WC) -l` - @count=0; \ - for i in `$(CAT) $<` ; do \ - f=$(JDK_TOPDIR)/$$i; \ - count=`$(EXPR) $$count '+' 1`; \ - if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \ - $(PRINTF) "\rChecked $$count files"; \ - fi; \ - if [ ! -f $$f ] ; then \ - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \ - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \ - elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \ - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \ - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \ - fi; \ - done; \ - $(PRINTF) "\rChecked $$count files\n" - -# -# Phonies to avoid accidents. -# -.PHONY: sccs_get - -endif diff --git a/jdk/make/common/shared/Defs-utils.gmk b/jdk/make/common/shared/Defs-utils.gmk index d7660c34878..10bad59bdf3 100644 --- a/jdk/make/common/shared/Defs-utils.gmk +++ b/jdk/make/common/shared/Defs-utils.gmk @@ -33,7 +33,7 @@ # UTILS_COMMAND_PATH # /usr/bin/ # UTILS_USR_BIN_PATH -# /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs) +# /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs) # UTILS_CCS_BIN_PATH # Dev Tools: zip, unzip, etc that we may have special versions of # UTILS_DEVTOOL_PATH @@ -117,7 +117,6 @@ RC = $(UTILS_COMMAND_PATH)rc RMDIR = $(UTILS_COMMAND_PATH)rmdir RPM = $(UTILS_COMMAND_PATH)rpm RPMBUILD = $(UTILS_COMMAND_PATH)rpmbuild -SCCS = $(UTILS_CCS_BIN_PATH)sccs SED = $(UTILS_COMMAND_PATH)sed SH = $(UTILS_COMMAND_PATH)sh SHOWREV = $(UTILS_USR_BIN_PATH)showrev @@ -183,7 +182,7 @@ ifeq ($(PLATFORM),linux) NAWK = $(USRBIN_PATH)gawk # Intrinsic unix command, with backslash-escaped character interpretation ECHO = /bin/echo -e - # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not) + # These are really in UTILS_USR_BIN_PATH on Linux AR = $(UTILS_USR_BIN_PATH)ar AS = $(UTILS_USR_BIN_PATH)as LD = $(UTILS_USR_BIN_PATH)ld diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 831b3a190e6..ed75606e211 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -165,6 +165,12 @@ java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java generic-all # very small tests and could greatly benefit from a samevm test run. # So a large batch of beans tests are currently run with othervm mode. +# Filed 6986807 +java/beans/Introspector/TestTypeResolver.java generic-all + +# Filed 6986813 +java/beans/Introspector/memory/Test4508780.java generic-all + # Linux, some kind of problems with X11 display java/beans/PropertyChangeSupport/Test4682386.java generic-all java/beans/PropertyChangeSupport/TestSynchronization.java generic-all @@ -493,6 +499,9 @@ java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java generic-all # jdk_security +# Filed 6986868 +sun/security/tools/jarsigner/crl.sh generic-all + # Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9 sun/security/krb5/auto/MaxRetries.java generic-all @@ -689,10 +698,22 @@ java/text/Bidi/Bug6665028.java linux-x64 # jdk_tools +# Filed 6952105 +com/sun/jdi/SuspendThreadTest.java generic-all + +# Filed 6986875 +sun/tools/jps/jps-Vvml.sh generic-all + +# Filed 6979016 +sun/tools/jconsole/ResourceCheckTest.sh generic-all + ############################################################################ # jdk_util +# Filed 6933803 +java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java generic-all + # Fails with assertion error on windows # 11 separate stacktraces created... file reuse problem? java/util/zip/ZipFile/ReadLongZipFileName.java generic-all From b32aa9d2d533136a8beadbfc9bcd873038d609f0 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sat, 25 Sep 2010 10:21:30 +0800 Subject: [PATCH 34/88] 6986868: TEST failure: sun/security/tools/jarsigner/crl.sh Reviewed-by: ohair --- jdk/test/sun/security/tools/jarsigner/crl.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/jdk/test/sun/security/tools/jarsigner/crl.sh b/jdk/test/sun/security/tools/jarsigner/crl.sh index 8eb70f9a9a0..b563c523cc4 100644 --- a/jdk/test/sun/security/tools/jarsigner/crl.sh +++ b/jdk/test/sun/security/tools/jarsigner/crl.sh @@ -63,7 +63,15 @@ $KT -alias a -gencrl -id 3:3 -id 4:4 -file crl2 $KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300 $KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3 -$TESTJAVA${FS}bin${FS}jrunscript -e 'println(new File("crl1").toURI())' > uri +cat > ToURI.java < uri $KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \ -ext crl=uri:`cat uri` From b90f2341f9aff8ada5f4200dc817ed70514393c9 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 27 Sep 2010 13:38:49 +0400 Subject: [PATCH 35/88] 6976577: JCK7 api/java_beans/EventSetDescriptor/descriptions.html#Ctor1 fails since jdk7 b102 Reviewed-by: peterz --- .../java/beans/EventSetDescriptor.java | 5 +- .../java/beans/IndexedPropertyDescriptor.java | 10 +- .../classes/java/beans/Introspector.java | 100 ++++++++++++++---- .../classes/java/beans/MethodDescriptor.java | 4 +- .../java/beans/PropertyDescriptor.java | 10 +- .../Introspector/6976577/Test6976577.java | 71 +++++++++++++ .../Introspector/6976577/test/Accessor.java | 81 ++++++++++++++ 7 files changed, 251 insertions(+), 30 deletions(-) create mode 100644 jdk/test/java/beans/Introspector/6976577/Test6976577.java create mode 100644 jdk/test/java/beans/Introspector/6976577/test/Accessor.java diff --git a/jdk/src/share/classes/java/beans/EventSetDescriptor.java b/jdk/src/share/classes/java/beans/EventSetDescriptor.java index db592aa8e3e..83b5e0d8f1c 100644 --- a/jdk/src/share/classes/java/beans/EventSetDescriptor.java +++ b/jdk/src/share/classes/java/beans/EventSetDescriptor.java @@ -176,8 +176,9 @@ public class EventSetDescriptor extends FeatureDescriptor { setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1)); // Be more forgiving of not finding the getListener method. - if (getListenerMethodName != null) { - setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName)); + Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0); + if (method != null) { + setGetListenerMethod(method); } } diff --git a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java index de439c7f911..5764bf49b76 100644 --- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java @@ -189,11 +189,13 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); } } - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class); + + Class[] args = { int.class }; + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); if (indexedReadMethod == null) { // no "is" method, so look for a "get" method. indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class); + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); } setIndexedReadMethod0(indexedReadMethod); } @@ -265,7 +267,9 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { if (indexedWriteMethodName == null) { indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName(); } - indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type); + + Class[] args = (type == null) ? null : new Class[] { int.class, type }; + indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args); if (indexedWriteMethod != null) { if (!indexedWriteMethod.getReturnType().equals(void.class)) { indexedWriteMethod = null; diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java index d7669bb7fd9..23e91d98b3c 100644 --- a/jdk/src/share/classes/java/beans/Introspector.java +++ b/jdk/src/share/classes/java/beans/Introspector.java @@ -28,7 +28,6 @@ package java.beans; import com.sun.beans.WeakCache; import com.sun.beans.finder.BeanInfoFinder; import com.sun.beans.finder.ClassFinder; -import com.sun.beans.finder.MethodFinder; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -843,8 +842,8 @@ public class Introspector { Method read = result.getReadMethod(); if (read == null && write != null) { - read = findInstanceMethod(result.getClass0(), - GET_PREFIX + NameGenerator.capitalize(result.getName())); + read = findMethod(result.getClass0(), + GET_PREFIX + NameGenerator.capitalize(result.getName()), 0); if (read != null) { try { result.setReadMethod(read); @@ -854,9 +853,9 @@ public class Introspector { } } if (write == null && read != null) { - write = findInstanceMethod(result.getClass0(), - SET_PREFIX + NameGenerator.capitalize(result.getName()), - FeatureDescriptor.getReturnType(result.getClass0(), read)); + write = findMethod(result.getClass0(), + SET_PREFIX + NameGenerator.capitalize(result.getName()), 1, + new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) }); if (write != null) { try { result.setWriteMethod(write); @@ -1280,27 +1279,90 @@ public class Introspector { // Package private support methods. //====================================================================== - static Method findMethod(Class type, String name, int args) { - for (Method method : type.getMethods()) { - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) { - try { - return MethodFinder.findAccessibleMethod(method); + /** + * Internal support for finding a target methodName with a given + * parameter list on a given class. + */ + private static Method internalFindMethod(Class start, String methodName, + int argCount, Class args[]) { + // For overriden methods we need to find the most derived version. + // So we start with the given class and walk up the superclass chain. + + Method method = null; + + for (Class cl = start; cl != null; cl = cl.getSuperclass()) { + Method methods[] = getPublicDeclaredMethods(cl); + for (int i = 0; i < methods.length; i++) { + method = methods[i]; + if (method == null) { + continue; } - catch (NoSuchMethodException exception) { - // continue search for a method with the specified count of parameters + + // make sure method signature matches. + Class params[] = FeatureDescriptor.getParameterTypes(start, method); + if (method.getName().equals(methodName) && + params.length == argCount) { + if (args != null) { + boolean different = false; + if (argCount > 0) { + for (int j = 0; j < argCount; j++) { + if (params[j] != args[j]) { + different = true; + continue; + } + } + if (different) { + continue; + } + } + } + return method; } } } - return null; + method = null; + + // Now check any inherited interfaces. This is necessary both when + // the argument class is itself an interface, and when the argument + // class is an abstract class. + Class ifcs[] = start.getInterfaces(); + for (int i = 0 ; i < ifcs.length; i++) { + // Note: The original implementation had both methods calling + // the 3 arg method. This is preserved but perhaps it should + // pass the args array instead of null. + method = internalFindMethod(ifcs[i], methodName, argCount, null); + if (method != null) { + break; + } + } + return method; } - static Method findInstanceMethod(Class type, String name, Class... args) { - try { - return MethodFinder.findInstanceMethod(type, name, args); - } - catch (NoSuchMethodException exception) { + /** + * Find a target methodName on a given class. + */ + static Method findMethod(Class cls, String methodName, int argCount) { + return findMethod(cls, methodName, argCount, null); + } + + /** + * Find a target methodName with specific parameter list on a given class. + *

    + * Used in the contructors of the EventSetDescriptor, + * PropertyDescriptor and the IndexedPropertyDescriptor. + *

    + * @param cls The Class object on which to retrieve the method. + * @param methodName Name of the method. + * @param argCount Number of arguments for the desired method. + * @param args Array of argument types for the method. + * @return the method or null if not found + */ + static Method findMethod(Class cls, String methodName, int argCount, + Class args[]) { + if (methodName == null) { return null; } + return internalFindMethod(cls, methodName, argCount, args); } /** diff --git a/jdk/src/share/classes/java/beans/MethodDescriptor.java b/jdk/src/share/classes/java/beans/MethodDescriptor.java index 74a7a16782d..d9e78be516f 100644 --- a/jdk/src/share/classes/java/beans/MethodDescriptor.java +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java @@ -90,13 +90,13 @@ public class MethodDescriptor extends FeatureDescriptor { // Find methods for up to 2 params. We are guessing here. // This block should never execute unless the classloader // that loaded the argument classes disappears. - method = Introspector.findMethod(cls, name, i); + method = Introspector.findMethod(cls, name, i, null); if (method != null) { break; } } } else { - method = Statement.getMethod(cls, name, params); + method = Introspector.findMethod(cls, name, params.length, params); } setMethod(method); } diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java index c7524e3026f..429d2b4079b 100644 --- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java @@ -112,7 +112,8 @@ public class PropertyDescriptor extends FeatureDescriptor { // If this class or one of its base classes allow PropertyChangeListener, // then we assume that any properties we discover are "bound". // See Introspector.getTargetPropertyInfo() method. - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class); + Class[] args = { PropertyChangeListener.class }; + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args); } /** @@ -223,10 +224,10 @@ public class PropertyDescriptor extends FeatureDescriptor { // property type is. For booleans, there can be "is" and "get" // methods. If an "is" method exists, this is the official // reader method so look for this one first. - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); if (readMethod == null) { readMethodName = Introspector.GET_PREFIX + getBaseName(); - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); } try { setReadMethod(readMethod); @@ -291,7 +292,8 @@ public class PropertyDescriptor extends FeatureDescriptor { writeMethodName = Introspector.SET_PREFIX + getBaseName(); } - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type); + Class[] args = (type == null) ? null : new Class[] { type }; + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args); if (writeMethod != null) { if (!writeMethod.getReturnType().equals(void.class)) { writeMethod = null; diff --git a/jdk/test/java/beans/Introspector/6976577/Test6976577.java b/jdk/test/java/beans/Introspector/6976577/Test6976577.java new file mode 100644 index 00000000000..61e1771231f --- /dev/null +++ b/jdk/test/java/beans/Introspector/6976577/Test6976577.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6976577 + * @summary Tests public methods in non-public beans + * @author Sergey Malenkov + */ + +import test.Accessor; + +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +public class Test6976577 { + + public static void main(String[] args) throws Exception { + Class bt = Accessor.getBeanType(); + Class lt = Accessor.getListenerType(); + + // test PropertyDescriptor + PropertyDescriptor pd = new PropertyDescriptor("boolean", bt); + test(pd.getReadMethod()); + test(pd.getWriteMethod()); + + // test IndexedPropertyDescriptor + IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt); + test(ipd.getReadMethod()); + test(ipd.getWriteMethod()); + test(ipd.getIndexedReadMethod()); + test(ipd.getIndexedWriteMethod()); + + // test EventSetDescriptor + EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process"); + test(esd.getAddListenerMethod()); + test(esd.getRemoveListenerMethod()); + test(esd.getGetListenerMethod()); + test(esd.getListenerMethods()); + } + + private static void test(Method... methods) { + for (Method method : methods) { + if (method == null) { + throw new Error("public method is not found"); + } + } + } +} diff --git a/jdk/test/java/beans/Introspector/6976577/test/Accessor.java b/jdk/test/java/beans/Introspector/6976577/test/Accessor.java new file mode 100644 index 00000000000..a7a7090bc11 --- /dev/null +++ b/jdk/test/java/beans/Introspector/6976577/test/Accessor.java @@ -0,0 +1,81 @@ +package test; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.EventListener; +import java.util.TooManyListenersException; + +public class Accessor { + + public static Class getBeanType() { + return Bean.class; + } + + public static Class getListenerType() { + return TestListener.class; + } +} + +interface TestEvent { +} + +interface TestListener extends EventListener { + void process(TestEvent event); +} + +class Bean { + + private boolean b; + private int[] indexed; + private TestListener listener; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + + public void addPropertyChangeListener(PropertyChangeListener listener) { + this.pcs.addPropertyChangeListener(listener); + } + + public void addTestListener(TestListener listener) throws TooManyListenersException { + if (listener != null) { + if (this.listener != null) { + throw new TooManyListenersException(); + } + this.listener = listener; + } + } + + public void removeTestListener(TestListener listener) { + if (this.listener == listener) { + this.listener = null; + } + } + + public TestListener[] getTestListeners() { + return (this.listener != null) + ? new TestListener[] { this.listener } + : new TestListener[0]; + } + + public boolean isBoolean() { + return this.b; + } + + public void setBoolean(boolean b) { + this.b = b; + } + + public int[] getIndexed() { + return this.indexed; + } + + public void setIndexed(int[] values) { + this.indexed = values; + } + + public int getIndexed(int index) { + return this.indexed[index]; + } + + public void setIndexed(int index, int value) { + this.indexed[index] = value; + } +} From 397abc7260b70fad7a46ce395bd60ddd48df0ba9 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Mon, 27 Sep 2010 16:11:58 +0400 Subject: [PATCH 36/88] 6505819: Provide traverseIn method for sun.awt.EmbeddedFrame Reviewed-by: dcherepanov, art --- .../java/awt/KeyboardFocusManager.java | 3 ++ .../share/classes/sun/awt/AWTAccessor.java | 5 +++ .../share/classes/sun/awt/EmbeddedFrame.java | 40 ++++++++++++++++++- .../classes/sun/awt/X11/XEmbeddedFrame.java | 32 +++++++++++++++ .../sun/awt/X11/XEmbeddedFramePeer.java | 18 +++++++++ .../sun/awt/windows/WEmbeddedFrame.java | 15 ++++++- 6 files changed, 110 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 0c272763508..07ecefe1def 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -142,6 +142,9 @@ public abstract class KeyboardFocusManager public void removeLastFocusRequest(Component heavyweight) { KeyboardFocusManager.removeLastFocusRequest(heavyweight); } + public void setMostRecentFocusOwner(Window window, Component component) { + KeyboardFocusManager.setMostRecentFocusOwner(window, component); + } } ); } diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 669f15ad8b8..27609806967 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -344,6 +344,11 @@ public final class AWTAccessor { * Removes the last focus request for the heavyweight from the queue. */ void removeLastFocusRequest(Component heavyweight); + + /* + * Sets the most recent focus owner in the window. + */ + void setMostRecentFocusOwner(Window window, Component component); } /* diff --git a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java index b3e6a2f7801..96b1325f8cb 100644 --- a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java +++ b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java @@ -70,7 +70,10 @@ public abstract class EmbeddedFrame extends Frame // JDK 1.1 compatibility private static final long serialVersionUID = 2967042741780317130L; - // Use these in traverseOut method to determine directions + /* + * The constants define focus traversal directions. + * Use them in {@code traverseIn}, {@code traverseOut} methods. + */ protected static final boolean FORWARD = true; protected static final boolean BACKWARD = false; @@ -283,6 +286,41 @@ public abstract class EmbeddedFrame extends Frame return false; } + /** + * This method is called by the embedder when we should receive focus as element + * of the traversal chain. The method requests focus on: + * 1. the first Component of this EmbeddedFrame if user moves focus forward + * in the focus traversal cycle. + * 2. the last Component of this EmbeddedFrame if user moves focus backward + * in the focus traversal cycle. + * + * The direction parameter specifies which of the two mentioned cases is + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class + * to avoid confusing boolean values. + * + * A concrete implementation of this method is defined in the platform-dependent + * subclasses. + * + * @param direction FORWARD or BACKWARD + * @return true, if the EmbeddedFrame wants to get focus, false otherwise. + */ + public boolean traverseIn(boolean direction) { + Component comp = null; + + if (direction == FORWARD) { + comp = getFocusTraversalPolicy().getFirstComponent(this); + } else { + comp = getFocusTraversalPolicy().getLastComponent(this); + } + if (comp != null) { + // comp.requestFocus(); - Leads to a hung. + + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp); + synthesizeWindowActivation(true); + } + return (null != comp); + } + /** * This method is called from dispatchKeyEvent in the following two cases: * 1. The focus is on the first Component of this EmbeddedFrame and we are diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java index 221ffb5e326..e9d0fcb6e7a 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java @@ -28,9 +28,12 @@ package sun.awt.X11; import sun.awt.EmbeddedFrame; import java.awt.*; import java.awt.AWTKeyStroke; +import java.util.logging.Logger; public class XEmbeddedFrame extends EmbeddedFrame { + private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName()); + long handle; public XEmbeddedFrame() { } @@ -70,6 +73,21 @@ public class XEmbeddedFrame extends EmbeddedFrame { this(handle, supportsXEmbed, false); } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public boolean traverseIn(boolean direction) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + return super.traverseIn(direction); + } + } + return false; + } + protected boolean traverseOut(boolean direction) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (direction == FORWARD) { @@ -81,6 +99,20 @@ public class XEmbeddedFrame extends EmbeddedFrame { return true; } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public void synthesizeWindowActivation(boolean doActivate) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + peer.synthesizeFocusInOut(doActivate); + } + } + } + public void registerAccelerator(AWTKeyStroke stroke) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (xefp != null) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java index 5825277207b..9fee20f90df 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java @@ -35,6 +35,8 @@ import sun.util.logging.PlatformLogger; import sun.awt.EmbeddedFrame; import sun.awt.SunToolkit; +import static sun.awt.X11.XConstants.*; + public class XEmbeddedFramePeer extends XFramePeer { private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer"); @@ -305,4 +307,20 @@ public class XEmbeddedFramePeer extends XFramePeer { EmbeddedFrame frame = (EmbeddedFrame)target; frame.notifyModalBlocked(blocker, blocked); } + + public void synthesizeFocusInOut(boolean doFocus) { + XFocusChangeEvent xev = new XFocusChangeEvent(); + + XToolkit.awtLock(); + try { + xev.set_type(doFocus ? FocusIn : FocusOut); + xev.set_window(getFocusProxy().getWindow()); + xev.set_mode(NotifyNormal); + XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false, + NoEventMask, xev.pData); + } finally { + XToolkit.awtUnlock(); + xev.dispose(); + } + } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java index 18489f91db4..908c1aac8e2 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java +++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java @@ -191,9 +191,20 @@ public class WEmbeddedFrame extends EmbeddedFrame { public void activateEmbeddingTopLevel() { } - public void synthesizeWindowActivation(boolean doActivate) { - ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + public void synthesizeWindowActivation(final boolean doActivate) { + if (!doActivate || EventQueue.isDispatchThread()) { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + } else { + // To avoid focus concurrence b/w IE and EmbeddedFrame + // activation is postponed by means of posting it to EDT. + EventQueue.invokeLater(new Runnable() { + public void run() { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true); + } + }); + } } + public void registerAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {} From 096941040720b5d0fe59778403c75635f7409571 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Mon, 27 Sep 2010 17:38:57 +0400 Subject: [PATCH 37/88] 6886678: Clicking on parent JFrame's client area does not switch focus from JWindow to JFrame on Windows Reviewed-by: dcherepanov, art --- .../native/sun/windows/awt_Component.cpp | 13 ++ .../FocusOwnerFrameOnClick.java | 125 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 54bfbb47a16..71307cb9e58 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -2329,6 +2329,19 @@ MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button) MSG msg; InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); + AwtWindow *toplevel = GetContainer(); + if (toplevel && !toplevel->IsSimpleWindow()) { + /* + * The frame should be focused by click in case it is + * the active window but not the focused window. See 6886678. + */ + if (toplevel->GetHWnd() == ::GetActiveWindow() && + toplevel->GetHWnd() != AwtComponent::GetFocusedWindow()) + { + toplevel->AwtSetActiveWindow(); + } + } + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y, GetJavaModifiers(), clickCount, JNI_FALSE, GetButton(button), &msg); diff --git a/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java b/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java new file mode 100644 index 00000000000..6c13b37aa0d --- /dev/null +++ b/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test FocusOwnerFrameOnClick.java %W% %E% + @bug 6886678 + @summary Tests that clicking an owner frame switches focus from its owned window. + @author Anton Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main FocusOwnerFrameOnClick +*/ + +import java.awt.*; +import java.awt.event.*; +import java.applet.Applet; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.reflect.InvocationTargetException; +import test.java.awt.regtesthelpers.Util; + +public class FocusOwnerFrameOnClick extends Applet { + Robot robot; + Frame frame = new Frame("Frame"); + Window window = new Window(frame); + Button fButton = new Button("fButton"); + Button wButton = new Button("wButton"); + + AtomicBoolean focused = new AtomicBoolean(false); + + public static void main(String[] args) { + FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick(); + app.init(); + app.start(); + } + + public void init() { + robot = Util.createRobot(); + + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.add(fButton); + + window.setLocation(300, 0); + window.add(wButton); + window.pack(); + } + + public void start() { + frame.setVisible(true); + Util.waitForIdle(robot); + + window.setVisible(true); + Util.waitForIdle(robot); + + if (!wButton.hasFocus()) { + if (!Util.trackFocusGained(wButton, new Runnable() { + public void run() { + Util.clickOnComp(wButton, robot); + } + }, 2000, false)) + { + throw new TestErrorException("wButton didn't gain focus on showing"); + } + } + + Runnable clickAction = new Runnable() { + public void run() { + Point loc = fButton.getLocationOnScreen(); + Dimension dim = fButton.getSize(); + + robot.mouseMove(loc.x, loc.y + dim.height + 20); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + }; + + if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) { + throw new TestFailedException("The frame wasn't focused on click"); + } + + System.out.println("Test passed."); + } +} + +/** + * Thrown when the behavior being verified is found wrong. + */ +class TestFailedException extends RuntimeException { + TestFailedException(String msg) { + super("Test failed: " + msg); + } +} + +/** + * Thrown when an error not related to the behavior being verified is encountered. + */ +class TestErrorException extends RuntimeException { + TestErrorException(String msg) { + super("Unexpected error: " + msg); + } +} From 625c4ba907ff924b503b54c07394619aaa3d184e Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Mon, 27 Sep 2010 11:30:03 -0400 Subject: [PATCH 38/88] 6986968: Crash on XIM server restart Free XIM data structures on DestroyXIMCallback Reviewed-by: naoto --- jdk/src/solaris/native/sun/awt/awt_InputMethod.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c index fbaf35cfff3..549e51986f6 100644 --- a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c +++ b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c @@ -1473,6 +1473,10 @@ static void OpenXIMCallback(Display *display, XPointer client_data, XPointer cal static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) { /* mark that XIM server was destroyed */ X11im = NULL; + JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + /* free the old pX11IMData and set it to null. this also avoids crashing + * the jvm if the XIM server reappears */ + X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance); } /* From 365010ff3eb8d87eeb7d06215fe2613bada88205 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 27 Sep 2010 21:07:45 +0400 Subject: [PATCH 39/88] 6986450: javax/swing/JTable/Test6888156.java test is failing against jdk7 just on windows Reviewed-by: alexp --- jdk/test/javax/swing/JTable/Test6888156.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/jdk/test/javax/swing/JTable/Test6888156.java b/jdk/test/javax/swing/JTable/Test6888156.java index 79809e582a1..f82d8026be4 100644 --- a/jdk/test/javax/swing/JTable/Test6888156.java +++ b/jdk/test/javax/swing/JTable/Test6888156.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,14 +71,14 @@ public class Test6888156 { table = new JTable(model); } - public void test(final LookAndFeel laf) throws Exception { + public void test(final String laf) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { try { + System.out.println(laf); UIManager.setLookAndFeel(laf); - } catch (UnsupportedLookAndFeelException e) { - System.err.println(laf.getDescription() + - " is unsupported; continuing"); + } catch (Exception e) { + System.err.println(laf + " is unsupported; continuing"); return; } SwingUtilities.updateComponentTreeUI(table); @@ -92,8 +92,10 @@ public class Test6888156 { public static void main(String[] args) throws Exception { Test6888156 t = new Test6888156(); - t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel()); - t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel()); + t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel"); + t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + t.test(laf.getClassName()); + } } } - From 26f967ece44baab85d25cd8b14a591180359be3a Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Sep 2010 14:05:33 -0700 Subject: [PATCH 40/88] 6890226: javah -version is broken Reviewed-by: darcy --- .../com/sun/tools/javah/JavahTask.java | 14 +++-- .../sun/tools/javah/resources/l10n.properties | 5 +- .../resources/version.properties-template | 28 +++++++++ langtools/test/tools/javah/VersionTest.java | 59 +++++++++++++++++++ 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template create mode 100644 langtools/test/tools/javah/VersionTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java index 650460a5c5d..0e885815dc2 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java +++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -526,15 +526,17 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } private void showVersion(boolean full) { - log.println(version(full ? "full" : "release")); + log.println(version(full)); } private static final String versionRBName = "com.sun.tools.javah.resources.version"; private static ResourceBundle versionRB; - private String version(String key) { - // key=version: mm.nn.oo[-milestone] - // key=full: mm.mm.oo[-milestone]-build + private String version(boolean full) { + String msgKey = (full ? "javah.fullVersion" : "javah.version"); + String versionKey = (full ? "full" : "release"); + // versionKey=product: mm.nn.oo[-milestone] + // versionKey=full: mm.mm.oo[-milestone]-build if (versionRB == null) { try { versionRB = ResourceBundle.getBundle(versionRBName); @@ -543,7 +545,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } } try { - return versionRB.getString(key); + return getMessage(msgKey, "javah", versionRB.getString(versionKey)); } catch (MissingResourceException e) { return getMessage("version.unknown", System.getProperty("java.version")); diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties index b9f175e5bf8..305e275b054 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -113,7 +113,8 @@ main.usage.foot=\ # # Version string. # -javah.version=javah version "{0}" +javah.version={0} version "{1}" +javah.fullVersion={0} full version "{1}" # # These should have better diagnostics. diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template b/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template new file mode 100644 index 00000000000..1e98afc90c7 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template @@ -0,0 +1,28 @@ +# +# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +jdk=$(JDK_VERSION) +full=$(FULL_VERSION) +release=$(RELEASE) diff --git a/langtools/test/tools/javah/VersionTest.java b/langtools/test/tools/javah/VersionTest.java new file mode 100644 index 00000000000..12e18d971bf --- /dev/null +++ b/langtools/test/tools/javah/VersionTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6890226 + * @summary javah -version is broken + */ + +import java.io.*; +import java.util.Locale; + +public class VersionTest { + public static void main(String... args) { + Locale prev = Locale.getDefault(); + try { + Locale.setDefault(Locale.ENGLISH); + System.err.println(Locale.getDefault()); + test("-version", "\\S+ version \"\\S+\""); + test("-fullversion", "\\S+ full version \"\\S+\""); + } finally { + Locale.setDefault(prev); + } + } + + static void test(String option, String regex) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { option }; + int rc = com.sun.tools.javah.Main.run(args, pw); + pw.close(); + if (rc != 0) + throw new Error("javah failed: rc=" + rc); + String out = sw.toString().trim(); + System.err.println(out); + if (!out.matches(regex)) + throw new Error("output does not match pattern: " + regex); + } +} From 2730836d77e56cd4a51186e63079f8ad1f36c548 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Sep 2010 14:20:39 -0700 Subject: [PATCH 41/88] 6877202: Elements.getDocComment() is not getting JavaDocComments 6861094: javac -Xprint does not print comments 6985205: access to tree positions and doc comments may be lost across annotation processing rounds Reviewed-by: darcy --- .../com/sun/tools/apt/main/JavaCompiler.java | 5 +- .../sun/tools/javac/api/JavacTaskImpl.java | 15 +- .../sun/tools/javac/main/JavaCompiler.java | 9 +- .../tools/javac/parser/DocCommentScanner.java | 39 +-- .../sun/tools/javac/parser/JavacParser.java | 7 +- .../sun/tools/javac/parser/ParserFactory.java | 8 +- .../com/sun/tools/javac/parser/Scanner.java | 50 +-- .../tools/javac/parser/ScannerFactory.java | 90 +++++ .../com/sun/tools/javadoc/JavadocTool.java | 5 +- .../test/tools/javac/6302184/T6302184.out | 3 + .../test/tools/javac/6304921/TestLog.java | 4 +- .../tools/javac/api/TestJavacTaskScanner.java | 22 +- .../elements/doccomments/TestDocComments.java | 309 ++++++++++++++++++ .../util/elements/doccomments/a/First.java | 54 +++ .../util/elements/doccomments/z/Last.java | 30 ++ .../processing/{ => options}/Xprint.java | 2 +- .../processing/options/XprintDocComments.java | 39 +++ .../processing/options/XprintDocComments.out | 12 + .../tools/javac/tree/TreePosRoundsTest.java | 204 ++++++++++++ 19 files changed, 785 insertions(+), 122 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java create mode 100644 langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java create mode 100644 langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java create mode 100644 langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java rename langtools/test/tools/javac/processing/{ => options}/Xprint.java (96%) create mode 100644 langtools/test/tools/javac/processing/options/XprintDocComments.java create mode 100644 langtools/test/tools/javac/processing/options/XprintDocComments.out create mode 100644 langtools/test/tools/javac/tree/TreePosRoundsTest.java diff --git a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java index 8d949541ca5..023712e4c3b 100644 --- a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,9 +99,6 @@ public class JavaCompiler extends com.sun.tools.javac.main.JavaCompiler { private static Context preRegister(Context context) { Bark.preRegister(context); - // force the use of the scanner that captures Javadoc comments - DocCommentScanner.Factory.preRegister(context); - if (context.get(JavaFileManager.class) == null) JavacFileManager.preRegister(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index 1e98ec9ce27..07e39a8c3bd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,9 +96,6 @@ public class JavacTaskImpl extends JavacTask { args.getClass(); context.getClass(); fileObjects.getClass(); - - // force the use of the scanner that captures Javadoc comments - com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context); } JavacTaskImpl(JavacTool tool, @@ -337,9 +334,13 @@ public class JavacTaskImpl extends JavacTask { ListBuffer elements = new ListBuffer(); for (JCCompilationUnit unit : units) { - for (JCTree node : unit.defs) - if (node.getTag() == JCTree.CLASSDEF) - elements.append(((JCTree.JCClassDecl) node).sym); + for (JCTree node : unit.defs) { + if (node.getTag() == JCTree.CLASSDEF) { + JCClassDecl cdef = (JCClassDecl) node; + if (cdef.sym != null) // maybe null if errors in anno processing + elements.append(cdef.sym); + } + } } return elements.toList(); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 43740c83098..04924fb9818 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,9 +62,6 @@ import static javax.tools.StandardLocation.CLASS_OUTPUT; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; import static com.sun.tools.javac.util.ListBuffer.lb; -// TEMP, until we have a more efficient way to save doc comment info -import com.sun.tools.javac.parser.DocCommentScanner; - import java.util.HashMap; import java.util.Queue; import javax.lang.model.SourceVersion; @@ -964,11 +961,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter { processAnnotations = procEnvImpl.atLeastOneProcessor(); if (processAnnotations) { - if (context.get(Scanner.Factory.scannerFactoryKey) == null) - DocCommentScanner.Factory.preRegister(context); options.put("save-parameter-names", "save-parameter-names"); reader.saveParameterNames = true; keepComments = true; + genEndPos = true; if (taskListener != null) taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); log.deferDiagnostics = true; @@ -1587,6 +1583,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { } public void initRound(JavaCompiler prev) { + genEndPos = prev.genEndPos; keepComments = prev.keepComments; start_msec = prev.start_msec; hasBeenUsed = true; diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java index d7803b89cd2..e6d687d4ca9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,50 +42,17 @@ import static com.sun.tools.javac.util.LayoutCharacters.*; */ public class DocCommentScanner extends Scanner { - /** A factory for creating scanners. */ - public static class Factory extends Scanner.Factory { - - public static void preRegister(final Context context) { - context.put(scannerFactoryKey, new Context.Factory() { - public Factory make() { - return new Factory(context); - } - }); - } - - /** Create a new scanner factory. */ - protected Factory(Context context) { - super(context); - } - - @Override - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new DocCommentScanner(this, (CharBuffer)input); - } else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - } - - @Override - public Scanner newScanner(char[] input, int inputLength) { - return new DocCommentScanner(this, input, inputLength); - } - } - - /** Create a scanner from the input buffer. buffer must implement * array() and compact(), and remaining() must be less than limit(). */ - protected DocCommentScanner(Factory fac, CharBuffer buffer) { + protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) { super(fac, buffer); } /** Create a scanner from the input array. The array must have at * least a single character of extra space. */ - protected DocCommentScanner(Factory fac, char[] input, int inputLength) { + protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) { super(fac, input, inputLength); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 3ca8b64dc8f..d4ec62a19a9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2473,6 +2473,11 @@ public class JavacParser implements Parser { defs.append(importDeclaration()); } else { JCTree def = typeDeclaration(mods); + if (keepDocComments && dc != null && docComments.get(def) == dc) { + // If the first type declaration has consumed the first doc + // comment, then don't use it for the top level comment as well. + dc = null; + } if (def instanceof JCExpressionStatement) def = ((JCExpressionStatement)def).expr; defs.append(def); diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java index 9dc794136dc..709bd5f1018 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ public class ParserFactory { final Source source; final Names names; final Options options; - final Scanner.Factory scannerFactory; + final ScannerFactory scannerFactory; protected ParserFactory(Context context) { super(); @@ -70,11 +70,11 @@ public class ParserFactory { this.keywords = Keywords.instance(context); this.source = Source.instance(context); this.options = Options.instance(context); - this.scannerFactory = Scanner.Factory.instance(context); + this.scannerFactory = ScannerFactory.instance(context); } public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { - Lexer lexer = scannerFactory.newScanner(input); + Lexer lexer = scannerFactory.newScanner(input, keepDocComments); if (keepEndPos) { return new EndPosParser(this, lexer, keepDocComments, keepLineMap); } else { diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java index ededb7eccf8..2b558d8fa39 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,48 +47,6 @@ public class Scanner implements Lexer { private static boolean scannerDebug = false; - /** A factory for creating scanners. */ - public static class Factory { - /** The context key for the scanner factory. */ - public static final Context.Key scannerFactoryKey = - new Context.Key(); - - /** Get the Factory instance for this context. */ - public static Factory instance(Context context) { - Factory instance = context.get(scannerFactoryKey); - if (instance == null) - instance = new Factory(context); - return instance; - } - - final Log log; - final Names names; - final Source source; - final Keywords keywords; - - /** Create a new scanner factory. */ - protected Factory(Context context) { - context.put(scannerFactoryKey, this); - this.log = Log.instance(context); - this.names = Names.instance(context); - this.source = Source.instance(context); - this.keywords = Keywords.instance(context); - } - - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new Scanner(this, (CharBuffer)input); - } else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - } - - public Scanner newScanner(char[] input, int inputLength) { - return new Scanner(this, input, inputLength); - } - } - /* Output variables; set by nextToken(): */ @@ -177,7 +135,7 @@ public class Scanner implements Lexer { private final Keywords keywords; /** Common code for constructors. */ - private Scanner(Factory fac) { + private Scanner(ScannerFactory fac) { log = fac.log; names = fac.names; keywords = fac.keywords; @@ -201,7 +159,7 @@ public class Scanner implements Lexer { /** Create a scanner from the input buffer. buffer must implement * array() and compact(), and remaining() must be less than limit(). */ - protected Scanner(Factory fac, CharBuffer buffer) { + protected Scanner(ScannerFactory fac, CharBuffer buffer) { this(fac, JavacFileManager.toArray(buffer), buffer.limit()); } @@ -216,7 +174,7 @@ public class Scanner implements Lexer { * @param inputLength the size of the input. * Must be positive and less than or equal to input.length. */ - protected Scanner(Factory fac, char[] input, int inputLength) { + protected Scanner(ScannerFactory fac, char[] input, int inputLength) { this(fac); eofPos = inputLength; if (inputLength == input.length) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java b/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java new file mode 100644 index 00000000000..86c9bb2b11c --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.parser; + +import java.nio.CharBuffer; + +import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; + + +/** + * A factory for creating scanners. + * + *

    This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice. + */ +public class ScannerFactory { + /** The context key for the scanner factory. */ + public static final Context.Key scannerFactoryKey = + new Context.Key(); + + /** Get the Factory instance for this context. */ + public static ScannerFactory instance(Context context) { + ScannerFactory instance = context.get(scannerFactoryKey); + if (instance == null) + instance = new ScannerFactory(context); + return instance; + } + + final Log log; + final Names names; + final Source source; + final Keywords keywords; + + /** Create a new scanner factory. */ + protected ScannerFactory(Context context) { + context.put(scannerFactoryKey, this); + this.log = Log.instance(context); + this.names = Names.instance(context); + this.source = Source.instance(context); + this.keywords = Keywords.instance(context); + } + + public Scanner newScanner(CharSequence input, boolean keepDocComments) { + if (input instanceof CharBuffer) { + CharBuffer buf = (CharBuffer) input; + if (keepDocComments) + return new DocCommentScanner(this, buf); + else + return new Scanner(this, buf); + } else { + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length, keepDocComments); + } + } + + public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { + if (keepDocComments) + return new DocCommentScanner(this, input, inputLength); + else + return new Scanner(this, input, inputLength); + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index 580eac04edd..cac7f991354 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,9 +107,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { // force the use of Messager as a Log messager = Messager.instance0(context); - // force the use of the scanner that captures Javadoc comments - DocCommentScanner.Factory.preRegister(context); - return new JavadocTool(context); } catch (CompletionFailure ex) { messager.error(Position.NOPOS, ex.getMessage()); diff --git a/langtools/test/tools/javac/6302184/T6302184.out b/langtools/test/tools/javac/6302184/T6302184.out index 4bfc1f79d78..e69f78750bc 100644 --- a/langtools/test/tools/javac/6302184/T6302184.out +++ b/langtools/test/tools/javac/6302184/T6302184.out @@ -1,4 +1,7 @@ +/** + * This is a test that uses ISO 8859 encoding. + */ class T6302184 { T6302184() { diff --git a/langtools/test/tools/javac/6304921/TestLog.java b/langtools/test/tools/javac/6304921/TestLog.java index 465a6e3cbbb..32217a45d35 100644 --- a/langtools/test/tools/javac/6304921/TestLog.java +++ b/langtools/test/tools/javac/6304921/TestLog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import javax.tools.SimpleJavaFileObject; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.parser.Parser; import com.sun.tools.javac.parser.ParserFactory; -import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; @@ -60,7 +59,6 @@ public class TestLog log.multipleErrors = true; JavacFileManager.preRegister(context); - Scanner.Factory sfac = Scanner.Factory.instance(context); ParserFactory pfac = ParserFactory.instance(context); final String text = diff --git a/langtools/test/tools/javac/api/TestJavacTaskScanner.java b/langtools/test/tools/javac/api/TestJavacTaskScanner.java index 245e2f6edb7..40bde1679e5 100644 --- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java +++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,8 @@ */ import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.parser.*; // XXX -import com.sun.tools.javac.util.*; // XXX +import com.sun.tools.javac.parser.*; +import com.sun.tools.javac.util.*; import java.io.*; import java.net.*; import java.nio.*; @@ -65,7 +65,7 @@ public class TestJavacTaskScanner extends ToolTester { fm.getJavaFileObjects(new File[] {file}); StandardJavaFileManager fm = getLocalFileManager(tool, null, null); task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits); - task.getContext().put(Scanner.Factory.scannerFactoryKey, + task.getContext().put(ScannerFactory.scannerFactoryKey, new MyScanner.Factory(task.getContext(), this)); elements = task.getElements(); types = task.getTypes(); @@ -170,34 +170,36 @@ public class TestJavacTaskScanner extends ToolTester { class MyScanner extends Scanner { - public static class Factory extends Scanner.Factory { + public static class Factory extends ScannerFactory { public Factory(Context context, TestJavacTaskScanner test) { super(context); this.test = test; } @Override - public Scanner newScanner(CharSequence input) { + public Scanner newScanner(CharSequence input, boolean keepDocComments) { + assert !keepDocComments; if (input instanceof CharBuffer) { return new MyScanner(this, (CharBuffer)input, test); } else { char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); + return newScanner(array, array.length, keepDocComments); } } @Override - public Scanner newScanner(char[] input, int inputLength) { + public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { + assert !keepDocComments; return new MyScanner(this, input, inputLength, test); } private TestJavacTaskScanner test; } - protected MyScanner(Factory fac, CharBuffer buffer, TestJavacTaskScanner test) { + protected MyScanner(ScannerFactory fac, CharBuffer buffer, TestJavacTaskScanner test) { super(fac, buffer); this.test = test; } - protected MyScanner(Factory fac, char[] input, int inputLength, TestJavacTaskScanner test) { + protected MyScanner(ScannerFactory fac, char[] input, int inputLength, TestJavacTaskScanner test) { super(fac, input, inputLength); this.test = test; } diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java new file mode 100644 index 00000000000..d96a79b3912 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6877202 + * @summary Elements.getDocComment() is not getting JavaDocComments + */ + +import com.sun.source.tree.*; +import com.sun.source.util.*; +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import javax.tools.*; + +/* + * For a mixture of pre-existing and generated source files, ensure that we can + * get the doc comments. + * The test uses both a standard ElementScanner to find all the elements being + * processed, and a TreeScanner to find all the local and anonymous inner classes + * as well. + * And, because the relevant code paths in the compiler are different for + * command line and JSR 199 invocation, the test covers both ways of invoking the + * compiler. + */ + +@SupportedOptions("scan") +@SupportedAnnotationTypes("*") +public class TestDocComments extends AbstractProcessor { + enum CompileKind { API, CMD }; + enum ScanKind { TREE, ELEMENT }; + + // ----- Main test driver: invoke compiler for the various test cases ------ + + public static void main(String... args) throws Exception { + for (CompileKind ck: CompileKind.values()) { + for (ScanKind sk: ScanKind.values()) { + try { + test(ck, sk); + } catch (IOException e) { + error(e.toString()); + } + } + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + static void test(CompileKind ck, ScanKind sk) throws IOException { + String testClasses = System.getProperty("test.classes"); + String testSrc = System.getProperty("test.src"); + File testDir = new File("test." + ck + "." + sk); + testDir.mkdirs(); + String[] opts = { + "-d", testDir.getPath(), + "-implicit:none", + "-processor", TestDocComments.class.getName(), + "-processorpath", testClasses, + //"-XprintRounds", + "-Ascan=" + sk + }; + File[] files = { + new File(testSrc, "a/First.java") + }; + + if (ck == CompileKind.API) + test_javac_api(opts, files); + else + test_javac_cmd(opts, files); + } + + static void test_javac_api(String[] opts, File[] files) throws IOException { + System.err.println("test javac api: " + Arrays.asList(opts) + " " + Arrays.asList(files)); + DiagnosticListener dl = new DiagnosticListener() { + public void report(Diagnostic diagnostic) { + error(diagnostic.toString()); + } + }; + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + Iterable units = fm.getJavaFileObjects(files); + JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); + t.parse(); + t.analyze(); + } + + static void test_javac_cmd(String[] opts, File[] files) { + System.err.println("test javac cmd: " + Arrays.asList(opts) + " " + Arrays.asList(files)); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + List args = new ArrayList(Arrays.asList(opts)); + for (File f: files) + args.add(f.getPath()); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc > 0) + error("Compilation failed: rc=" + rc); + } + + static void error(String msg) { + System.err.println(msg); + errors++; + //throw new Error(msg); + } + + static int errors; + + // ----- Annotation processor: scan for elements and check doc comments ---- + + Map options; + Filer filer; + Messager messager; + Elements elements; + ScanKind skind; + + int round = 0; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + options = pEnv.getOptions(); + filer = pEnv.getFiler(); + messager = pEnv.getMessager(); + elements = pEnv.getElementUtils(); + skind = ScanKind.valueOf(options.get("scan")); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + // Scan elements using an appropriate scanner, and for each element found, + // call check(Element e) to verify the doc comment on that element + for (Element e: roundEnv.getRootElements()) { + System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName()); + if (skind == ScanKind.TREE) { + Trees trees = Trees.instance(processingEnv); // cannot cache this across rounds + new TestTreeScanner().scan(trees.getPath(e), trees); + } else + new TestElementScanner().scan(e); + } + + // For a few rounds, generate new source files, so that we can check whether + // doc comments are correctly handled in subsequent processing rounds + final int MAX_ROUNDS = 3; + if (round <= MAX_ROUNDS) { + String pkg = "p"; + String currClass = "Gen" + round; + String curr = pkg + "." + currClass; + String next = (round < MAX_ROUNDS) ? (pkg + ".Gen" + (round + 1)) : "z.Last"; + StringBuilder text = new StringBuilder(); + text.append("package ").append(pkg).append(";\n"); + text.append("/** CLASS ").append(currClass).append(" */\n"); + text.append("public class ").append(currClass).append(" {\n"); + text.append(" /** CONSTRUCTOR **/\n"); + text.append(" ").append(currClass).append("() { }\n"); + text.append(" /** FIELD x */\n"); + text.append(" ").append(next).append(" x;\n"); + text.append(" /** METHOD m */\n"); + text.append(" void m() { }\n"); + text.append("}\n"); + + try { + JavaFileObject fo = filer.createSourceFile(curr); + Writer out = fo.openWriter(); + try { + out.write(text.toString()); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } + + return true; + } + + /* + * Check that the doc comment on an element is as expected. + * This method is invoked for each element found by the scanners run by process. + */ + void check(Element e) { + System.err.println("Checking " + e); + + String dc = elements.getDocComment(e); + System.err.println(" found " + dc); + + String expect = (e.getKind() + " " + e.getSimpleName()); // default + + Name name = e.getSimpleName(); + Element encl = e.getEnclosingElement(); + Name enclName = encl.getSimpleName(); + ElementKind enclKind = encl.getKind(); + switch (e.getKind()) { + case PARAMETER: + case LOCAL_VARIABLE: + // doc comments not retained for these elements + expect = null; + break; + + case CONSTRUCTOR: + if (enclName.length() == 0 || enclKind == ElementKind.ENUM) { + // Enum constructor is synthetic + expect = null; + } + break; + + case METHOD: + if (enclKind == ElementKind.ENUM + && (name.contentEquals("values") || name.contentEquals("valueOf"))) { + // synthetic enum methods + expect = null; + } + break; + + case CLASS: + if (e.getSimpleName().length() == 0) { + // anon inner class + expect = null; + } + break; + } + + System.err.println(" expect " + expect); + + if (dc == null ? expect == null : dc.trim().equals(expect)) + return; + + if (dc == null) + messager.printMessage(Diagnostic.Kind.ERROR, "doc comment is null", e); + else { + messager.printMessage(Diagnostic.Kind.ERROR, + "unexpected comment: \"" + dc + "\", expected \"" + expect + "\"", e); + } + } + + // ----- Scanners to find elements ----------------------------------------- + + class TestElementScanner extends ElementScanner7 { + @Override + public Void visitExecutable(ExecutableElement e, Void _) { + check(e); + return super.visitExecutable(e, _); + } + @Override + public Void visitType(TypeElement e, Void _) { + check(e); + return super.visitType(e, _); + } + @Override + public Void visitVariable(VariableElement e, Void _) { + check(e); + return super.visitVariable(e, _); + } + } + + class TestTreeScanner extends TreePathScanner { + @Override + public Void visitClass(ClassTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitClass(tree, trees); + } + @Override + public Void visitMethod(MethodTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitMethod(tree, trees); + } + @Override + public Void visitVariable(VariableTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitVariable(tree, trees); + } + } + +} diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java new file mode 100644 index 00000000000..1762abdb3db --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package a; + +/** CLASS First */ +public class First { + /** CONSTRUCTOR */ + First() { } + + /** FIELD x */ + p.Gen1 x; + + /** METHOD m **/ + void m(int i) { + /** CLASS Local */ + class Local { + /** CONSTRUCTOR */ + Local() { } + } + + Runnable r = new Runnable() { + /** METHOD run **/ + public void run() { } + }; + + } + + /** ENUM E */ + enum E { + /** ENUM_CONSTANT e1 */ + e1 + } +} diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java new file mode 100644 index 00000000000..eb017607a99 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package z; + +// This class should be read last, implicitly. Therefore it should not +// be subject to anno processing. If it is, the lack of doc comments should +// be detected and will flag an error. +public class Last { +} diff --git a/langtools/test/tools/javac/processing/Xprint.java b/langtools/test/tools/javac/processing/options/Xprint.java similarity index 96% rename from langtools/test/tools/javac/processing/Xprint.java rename to langtools/test/tools/javac/processing/options/Xprint.java index 6aae8795290..5417c89e82e 100644 --- a/langtools/test/tools/javac/processing/Xprint.java +++ b/langtools/test/tools/javac/processing/options/Xprint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/tools/javac/processing/options/XprintDocComments.java b/langtools/test/tools/javac/processing/options/XprintDocComments.java new file mode 100644 index 00000000000..cf61eb9c8f0 --- /dev/null +++ b/langtools/test/tools/javac/processing/options/XprintDocComments.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6861094 + * @summary javac -Xprint does not print comments + * @compile/ref=XprintDocComments.out -Xprint XprintDocComments.java + */ + +/** + * CLASS XprintDocComments + */ +class XPrintDocComments { + /** + * FIELD i; + */ + int i; +} diff --git a/langtools/test/tools/javac/processing/options/XprintDocComments.out b/langtools/test/tools/javac/processing/options/XprintDocComments.out new file mode 100644 index 00000000000..03b42b220d5 --- /dev/null +++ b/langtools/test/tools/javac/processing/options/XprintDocComments.out @@ -0,0 +1,12 @@ + +/** + * CLASS XprintDocComments + */ +class XPrintDocComments { + + XPrintDocComments(); + /** + * FIELD i; + */ + int i; +} diff --git a/langtools/test/tools/javac/tree/TreePosRoundsTest.java b/langtools/test/tools/javac/tree/TreePosRoundsTest.java new file mode 100644 index 00000000000..40ff35a5aa9 --- /dev/null +++ b/langtools/test/tools/javac/tree/TreePosRoundsTest.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6985205 + * @summary access to tree positions and doc comments may be lost across annotation processing rounds + * @build TreePosRoundsTest + * @compile -proc:only -processor TreePosRoundsTest TreePosRoundsTest.java + * @run main TreePosRoundsTest + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.*; + +import com.sun.source.tree.*; +import com.sun.source.util.*; +import javax.tools.JavaCompiler.CompilationTask; + +// This test is an annotation processor that performs multiple rounds of +// processing, and on each round, it checks that source positions are +// available and correct. +// +// The test can be run directly as a processor from the javac command line +// or via JSR 199 by invoking the main program. + +@SupportedAnnotationTypes("*") +public class TreePosRoundsTest extends AbstractProcessor { + public static void main(String... args) throws Exception { + String testSrc = System.getProperty("test.src"); + String testClasses = System.getProperty("test.classes"); + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + String thisName = TreePosRoundsTest.class.getName(); + File thisFile = new File(testSrc, thisName + ".java"); + Iterable files = fm.getJavaFileObjects(thisFile); + List options = Arrays.asList( + "-proc:only", + "-processor", thisName, + "-processorpath", testClasses); + CompilationTask t = c.getTask(null, fm, null, options, null, files); + boolean ok = t.call(); + if (!ok) + throw new Exception("processing failed"); + } + + Filer filer; + Messager messager; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + filer = pEnv.getFiler(); + messager = pEnv.getMessager(); + } + + int round = 0; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + // Scan trees for elements, verifying source tree positions + for (Element e: roundEnv.getRootElements()) { + try { + Trees trees = Trees.instance(processingEnv); // cannot cache this across rounds + TreePath p = trees.getPath(e); + new TestTreeScanner(p.getCompilationUnit(), trees).scan(trees.getPath(e), null); + } catch (IOException ex) { + messager.printMessage(Diagnostic.Kind.ERROR, + "Cannot get source: " + ex, e); + } + } + + final int MAXROUNDS = 3; + if (round < MAXROUNDS) + generateSource("Gen" + round); + + return true; + } + + void generateSource(String name) { + StringBuilder text = new StringBuilder(); + text.append("class ").append(name).append("{\n"); + text.append(" int one = 1;\n"); + text.append(" int two = 2;\n"); + text.append(" int three = one + two;\n"); + text.append("}\n"); + + try { + JavaFileObject fo = filer.createSourceFile(name); + Writer out = fo.openWriter(); + try { + out.write(text.toString()); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } + + class TestTreeScanner extends TreePathScanner { + TestTreeScanner(CompilationUnitTree unit, Trees trees) throws IOException { + this.unit = unit; + JavaFileObject sf = unit.getSourceFile(); + source = sf.getCharContent(true).toString(); + sourcePositions = trees.getSourcePositions(); + } + + @Override + public Void visitVariable(VariableTree tree, Void _) { + check(getCurrentPath()); + return super.visitVariable(tree, _); + } + + void check(TreePath tp) { + Tree tree = tp.getLeaf(); + + String expect = tree.toString(); + if (tree.getKind() == Tree.Kind.VARIABLE) { + // tree.toString() does not know enough context to add ";", + // so deal with that manually... + Tree.Kind enclKind = tp.getParentPath().getLeaf().getKind(); + //System.err.println(" encl: " +enclKind); + if (enclKind == Tree.Kind.CLASS || enclKind == Tree.Kind.BLOCK) + expect += ";"; + } + //System.err.println("expect: " + expect); + + int start = (int)sourcePositions.getStartPosition(unit, tree); + if (start == Diagnostic.NOPOS) { + messager.printMessage(Diagnostic.Kind.ERROR, "start pos not set for " + trim(tree)); + return; + } + + int end = (int)sourcePositions.getEndPosition(unit, tree); + if (end == Diagnostic.NOPOS) { + messager.printMessage(Diagnostic.Kind.ERROR, "end pos not set for " + trim(tree)); + return; + } + + String found = source.substring(start, end); + //System.err.println(" found: " + found); + + // allow for long lines, in which case just compare beginning and + // end of the strings + boolean equal; + if (found.contains("\n")) { + String head = found.substring(0, found.indexOf("\n")); + String tail = found.substring(found.lastIndexOf("\n")).trim(); + equal = expect.startsWith(head) && expect.endsWith(tail); + } else { + equal = expect.equals(found); + } + + if (!equal) { + messager.printMessage(Diagnostic.Kind.ERROR, + "unexpected value found: '" + found + "'; expected: '" + expect + "'"); + } + } + + String trim(Tree tree) { + final int MAXLEN = 32; + String s = tree.toString().replaceAll("\\s+", " ").trim(); + return (s.length() < MAXLEN) ? s : s.substring(0, MAXLEN); + + } + + CompilationUnitTree unit; + SourcePositions sourcePositions; + String source; + } + +} From d2bd33c26443238d30fb44fa1700fa19816fc546 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Mon, 27 Sep 2010 18:05:23 -0400 Subject: [PATCH 42/88] 6987638: javadoc update to RowSetProvider and Statement Reviewed-by: darcy, alanb --- jdk/src/share/classes/java/sql/Statement.java | 4 ++-- jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/sql/Statement.java b/jdk/src/share/classes/java/sql/Statement.java index 88684a79a57..d7f5bcfe19b 100644 --- a/jdk/src/share/classes/java/sql/Statement.java +++ b/jdk/src/share/classes/java/sql/Statement.java @@ -1051,9 +1051,9 @@ public interface Statement extends Wrapper, AutoCloseable { /** * Returns a value indicating whether this {@code Statement} will be - * closed when all dependent objects such as resultsets are closed. + * closed when all its dependent result sets are closed. * @return {@code true} if the {@code Statement} will be closed when all - * of its dependent objects are closed; {@code false} otherwise + * of its dependent result sets are closed; {@code false} otherwise * @throws SQLException if this method is called on a closed * {@code Statement} * @since 1.7 diff --git a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java index b5f9fe74634..75875c7b576 100644 --- a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java @@ -88,8 +88,8 @@ public class RowSetProvider { *

  • *
*
  • - * The ServiceLocator API. The ServiceLocator API will look - * for a classname in the file + * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look + * for a class name in the file * {@code META-INF/services/javax.sql.rowset.RowSetFactory} * in jars available to the runtime. For example, to have the the RowSetFactory * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the From 95a1a6096491bd2118e4bccde86b6ef87db957cb Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 27 Sep 2010 17:28:49 -0700 Subject: [PATCH 43/88] 6986246: Trees object is round-specific Reviewed-by: darcy --- .../com/sun/tools/javac/api/JavacTrees.java | 29 ++++++++++++------- .../JavacProcessingEnvironment.java | 9 +++++- .../elements/doccomments/TestDocComments.java | 5 ++-- .../tools/javac/tree/TreePosRoundsTest.java | 5 ++-- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index 889beb95c2a..e1c6053b27b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,6 @@ import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.MemberEnter; import com.sun.tools.javac.comp.Resolve; import com.sun.tools.javac.model.JavacElements; -import com.sun.tools.javac.processing.JavacMessager; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree; @@ -81,14 +80,15 @@ import com.sun.tools.javac.util.Pair; */ public class JavacTrees extends Trees { - private final Resolve resolve; - private final Enter enter; - private final Log log; - private final MemberEnter memberEnter; - private final Attr attr; - private final TreeMaker treeMaker; - private final JavacElements elements; - private final JavacTaskImpl javacTaskImpl; + // in a world of a single context per compilation, these would all be final + private Resolve resolve; + private Enter enter; + private Log log; + private MemberEnter memberEnter; + private Attr attr; + private TreeMaker treeMaker; + private JavacElements elements; + private JavacTaskImpl javacTaskImpl; public static JavacTrees instance(JavaCompiler.CompilationTask task) { if (!(task instanceof JavacTaskImpl)) @@ -111,6 +111,14 @@ public class JavacTrees extends Trees { private JavacTrees(Context context) { context.put(JavacTrees.class, this); + init(context); + } + + public void updateContext(Context context) { + init(context); + } + + private void init(Context context) { attr = Attr.instance(context); enter = Enter.instance(context); elements = JavacElements.instance(context); @@ -337,6 +345,7 @@ public class JavacTrees extends Trees { super(M); } + @Override public T copy(T t, JCTree leaf) { T t2 = super.copy(t, leaf); if (t == leaf) diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index f6623ef9028..b393fe52cb6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ import javax.tools.StandardJavaFileManager; import javax.tools.JavaFileObject; import javax.tools.DiagnosticListener; +import com.sun.tools.javac.api.JavacTrees; import com.sun.source.util.AbstractTypeProcessor; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; @@ -1104,6 +1105,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea task.updateContext(next); } + JavacTrees trees = context.get(JavacTrees.class); + if (trees != null) { + next.put(JavacTrees.class, trees); + trees.updateContext(next); + } + context.clear(); return next; } diff --git a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java index d96a79b3912..57cb1c3b014 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6877202 + * @bug 6877202 6986246 * @summary Elements.getDocComment() is not getting JavaDocComments */ @@ -139,6 +139,7 @@ public class TestDocComments extends AbstractProcessor { Filer filer; Messager messager; Elements elements; + Trees trees; ScanKind skind; int round = 0; @@ -155,6 +156,7 @@ public class TestDocComments extends AbstractProcessor { filer = pEnv.getFiler(); messager = pEnv.getMessager(); elements = pEnv.getElementUtils(); + trees = Trees.instance(processingEnv); skind = ScanKind.valueOf(options.get("scan")); } @@ -167,7 +169,6 @@ public class TestDocComments extends AbstractProcessor { for (Element e: roundEnv.getRootElements()) { System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName()); if (skind == ScanKind.TREE) { - Trees trees = Trees.instance(processingEnv); // cannot cache this across rounds new TestTreeScanner().scan(trees.getPath(e), trees); } else new TestElementScanner().scan(e); diff --git a/langtools/test/tools/javac/tree/TreePosRoundsTest.java b/langtools/test/tools/javac/tree/TreePosRoundsTest.java index 40ff35a5aa9..29a41b60795 100644 --- a/langtools/test/tools/javac/tree/TreePosRoundsTest.java +++ b/langtools/test/tools/javac/tree/TreePosRoundsTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6985205 + * @bug 6985205 6986246 * @summary access to tree positions and doc comments may be lost across annotation processing rounds * @build TreePosRoundsTest * @compile -proc:only -processor TreePosRoundsTest TreePosRoundsTest.java @@ -70,6 +70,7 @@ public class TreePosRoundsTest extends AbstractProcessor { Filer filer; Messager messager; + Trees trees; @Override public SourceVersion getSupportedSourceVersion() { @@ -81,6 +82,7 @@ public class TreePosRoundsTest extends AbstractProcessor { super.init(pEnv); filer = pEnv.getFiler(); messager = pEnv.getMessager(); + trees = Trees.instance(pEnv); } int round = 0; @@ -92,7 +94,6 @@ public class TreePosRoundsTest extends AbstractProcessor { // Scan trees for elements, verifying source tree positions for (Element e: roundEnv.getRootElements()) { try { - Trees trees = Trees.instance(processingEnv); // cannot cache this across rounds TreePath p = trees.getPath(e); new TestTreeScanner(p.getCompilationUnit(), trees).scan(trees.getPath(e), null); } catch (IOException ex) { From 07a295701d7e278d9a1394198f68d1aae7a916ba Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Tue, 28 Sep 2010 14:57:23 +0400 Subject: [PATCH 44/88] 6987896: Modal dialogs resumes the calling thread before it's hidden Reviewed-by: anthony --- jdk/src/share/classes/java/awt/Dialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/Dialog.java b/jdk/src/share/classes/java/awt/Dialog.java index 3e2effd1dc0..36a3502e3ba 100644 --- a/jdk/src/share/classes/java/awt/Dialog.java +++ b/jdk/src/share/classes/java/awt/Dialog.java @@ -1068,7 +1068,7 @@ public class Dialog extends Window { modalityPushed(); try { EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000); + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0); if (!secondaryLoop.enter()) { secondaryLoop = null; } From 2c29ae4f3c344672ca400593560da208c5ce6a7f Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Tue, 28 Sep 2010 11:59:57 +0100 Subject: [PATCH 45/88] 6550798: Using InputStream.skip with ResponseCache will cause partial data to be cached Reviewed-by: chegar --- .../www/protocol/http/HttpURLConnection.java | 32 +++++ .../www/protocol/http/6550798/TestCache.java | 133 ++++++++++++++++++ .../net/www/protocol/http/6550798/test.java | 90 ++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 jdk/test/sun/net/www/protocol/http/6550798/TestCache.java create mode 100644 jdk/test/sun/net/www/protocol/http/6550798/test.java diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index a9caf594953..ad45c983f29 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -2825,6 +2825,38 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + /* skip() calls read() in order to ensure that entire response gets + * cached. same implementation as InputStream.skip */ + + private byte[] skipBuffer; + private static final int SKIP_BUFFER_SIZE = 8096; + + @Override + public long skip (long n) throws IOException { + + long remaining = n; + int nr; + if (skipBuffer == null) + skipBuffer = new byte[SKIP_BUFFER_SIZE]; + + byte[] localSkipBuffer = skipBuffer; + + if (n <= 0) { + return 0; + } + + while (remaining > 0) { + nr = read(localSkipBuffer, 0, + (int) Math.min(SKIP_BUFFER_SIZE, remaining)); + if (nr < 0) { + break; + } + remaining -= nr; + } + + return n - remaining; + } + @Override public void close () throws IOException { try { diff --git a/jdk/test/sun/net/www/protocol/http/6550798/TestCache.java b/jdk/test/sun/net/www/protocol/http/6550798/TestCache.java new file mode 100644 index 00000000000..c90f3f5a018 --- /dev/null +++ b/jdk/test/sun/net/www/protocol/http/6550798/TestCache.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.*; +import java.io.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.PrintStream; +import java.io.InputStream; +import java.io.File; +import java.net.CacheRequest; +import java.net.CacheResponse; +import java.net.ResponseCache; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.jar.JarInputStream; +import java.util.jar.JarFile; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.security.PrivilegedActionException; +import java.security.Principal; +import java.security.cert.Certificate; +import javax.net.ssl.SSLPeerUnverifiedException; + +public class TestCache extends java.net.ResponseCache { + private boolean inCacheHandler = false; + private boolean _downloading = false; + + public static volatile boolean fail = false; + + public static void reset() { + // Set system wide cache handler + System.out.println("install deploy cache handler"); + ResponseCache.setDefault(new TestCache()); + } + + public synchronized CacheResponse get(final URI uri, String rqstMethod, + Map requestHeaders) throws IOException { + System.out.println("get: " + uri); + Thread.currentThread().dumpStack(); + return null; + } + + public synchronized CacheRequest put(URI uri, URLConnection conn) + throws IOException { + System.out.println("put: " + uri); + Thread.currentThread().dumpStack(); + URL url = uri.toURL(); + return new DeployCacheRequest(url, conn); + + } +} + +class DeployByteArrayOutputStream extends java.io.ByteArrayOutputStream { + + private URL _url; + private URLConnection _conn; + + DeployByteArrayOutputStream(URL url, URLConnection conn) { + _url = url; + _conn = conn; + } + + + public void close() throws IOException { + + System.out.println("contentLength: " + _conn.getContentLength()); + System.out.println("byte array size: " + size()); + if ( _conn.getContentLength() == size()) { + System.out.println("correct content length"); + } else { + System.out.println("wrong content length"); + System.out.println("TEST FAILED"); + TestCache.fail = true; + } + super.close(); + } +} + +class DeployCacheRequest extends java.net.CacheRequest { + + private URL _url; + private URLConnection _conn; + private boolean _downloading = false; + + DeployCacheRequest(URL url, URLConnection conn) { + System.out.println("DeployCacheRequest ctor for: " + url); + _url = url; + _conn = conn; + } + + public void abort() { + System.out.println("abort called"); + } + + public OutputStream getBody() throws IOException { + System.out.println("getBody called"); + return new DeployByteArrayOutputStream(_url, _conn); + } +} diff --git a/jdk/test/sun/net/www/protocol/http/6550798/test.java b/jdk/test/sun/net/www/protocol/http/6550798/test.java new file mode 100644 index 00000000000..9bcf5f91548 --- /dev/null +++ b/jdk/test/sun/net/www/protocol/http/6550798/test.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6550798 + * @summary Using InputStream.skip with ResponseCache will cause partial data to be cached + * @run main/othervm test + */ + +import java.net.*; +import com.sun.net.httpserver.*; +import java.io.*; + +public class test { + + final static int LEN = 16 * 1024; + + public static void main(String[] args) throws Exception { + + TestCache.reset(); + HttpServer s = HttpServer.create (new InetSocketAddress(0), 10); + s.createContext ("/", new HttpHandler () { + public void handle (HttpExchange e) { + try { + byte[] buf = new byte [LEN]; + OutputStream o = e.getResponseBody(); + e.sendResponseHeaders(200, LEN); + o.write (buf); + e.close(); + } catch (IOException ex) { + ex.printStackTrace(); + TestCache.fail = true; + } + } + }); + s.start(); + + System.out.println("http request with cache hander"); + URL u = new URL("http://127.0.0.1:"+s.getAddress().getPort()+"/f"); + URLConnection conn = u.openConnection(); + + InputStream is = null; + try { + // this calls into TestCache.get + byte[] buf = new byte[8192]; + is = new BufferedInputStream(conn.getInputStream()); + + is.skip(1000); + + while (is.read(buf) != -1) { + } + } finally { + if (is != null) { + // this calls into TestCache.put + // TestCache.put will check if the resource + // should be cached + is.close(); + } + s.stop(0); + } + + if (TestCache.fail) { + System.out.println ("TEST FAILED"); + throw new RuntimeException (); + } else { + System.out.println ("TEST OK"); + } + } +} From 2cd0e300b804f418e23b839b38e4762cb6ab0861 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Tue, 28 Sep 2010 14:36:19 +0100 Subject: [PATCH 46/88] 6987927: can't use -Dfile.encoding=Cp037 in net test Reviewed-by: chegar --- .../ChunkedInputStream/ChunkedCharEncoding.sh | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh deleted file mode 100644 index 927e951bea0..00000000000 --- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code 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 -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - - # @test - # @bug 6502503 - # @run shell/timeout=140 ChunkedCharEncoding.sh - # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked - -OS=`uname -s` -case "$OS" in - SunOS | Linux ) - PS=":" - FS="/" - ;; - CYGWIN* ) - PS=";" - FS="/" - ;; - Windows* ) - PS=";" - FS="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -# compile -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java - -# run with CP037 encoding specified. -${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1 - -result=$? -if [ "$result" -ne "0" ]; then - exit 1 -fi - -# no failures, exit. -exit 0 - From 6e5fbc5669121289133ebf7f3a52f74f13697bb0 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Tue, 28 Sep 2010 10:16:18 -0400 Subject: [PATCH 47/88] 6987945: XDecoratedPeer shouldn't allow to resize a frame to zero size Reviewed-by: anthony --- jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java | 8 ++------ jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java index c40e87b894a..45c29daa6fd 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java @@ -705,12 +705,8 @@ public class XBaseWindow { throw new IllegalStateException("Attempt to resize uncreated window"); } insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height); - if (width <= 0) { - width = 1; - } - if (height <= 0) { - height = 1; - } + width = Math.max(MIN_SIZE, width); + height = Math.max(MIN_SIZE, height); XToolkit.awtLock(); try { XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index 5618fa6f58c..340747f689c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -763,12 +763,8 @@ abstract class XDecoratedPeer extends XWindowPeer { } private void checkShellRectSize(Rectangle shellRect) { - if (shellRect.width < 0) { - shellRect.width = 1; - } - if (shellRect.height < 0) { - shellRect.height = 1; - } + shellRect.width = Math.max(MIN_SIZE, shellRect.width); + shellRect.height = Math.max(MIN_SIZE, shellRect.height); } private void checkShellRectPos(Rectangle shellRect) { From 55a531c45f5d6b2a5291c0b4f01fa2d30c21c047 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 28 Sep 2010 22:46:36 +0530 Subject: [PATCH 48/88] 6967842: Element not returned from tree API for ARM resource variables Reviewed-by: jjg, darcy --- .../com/sun/tools/javac/code/Symbol.java | 4 +- .../model/element/TestResourceElement.java | 96 +++++++++++++++++++ .../model/element/TestResourceVariable.java | 4 +- 3 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javac/processing/model/element/TestResourceElement.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 5e0838fb63d..afce2e30723 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -960,6 +960,8 @@ public abstract class Symbol implements Element { return ElementKind.ENUM_CONSTANT; } else if (owner.kind == TYP || owner.kind == ERR) { return ElementKind.FIELD; + } else if (isResourceVariable()) { + return ElementKind.RESOURCE_VARIABLE; } else { return ElementKind.LOCAL_VARIABLE; } diff --git a/langtools/test/tools/javac/processing/model/element/TestResourceElement.java b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java new file mode 100644 index 00000000000..9bb71b829a1 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6967842 + * @summary Element not returned from tree API for ARM resource variables. + * @author A. Sundararajan + * @build TestResourceElement + * @compile -processor TestResourceElement -proc:only TestResourceElement.java + */ + +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import java.util.*; +import com.sun.source.tree.*; +import com.sun.source.util.*; + +@SupportedAnnotationTypes("*") +public class TestResourceElement extends AbstractProcessor implements AutoCloseable { + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + Trees trees = Trees.instance(processingEnv); + + for(Element rootElement : roundEnv.getRootElements()) { + TreePath treePath = trees.getPath(rootElement); + + VariableScanner varScanner = new VariableScanner(trees); + varScanner.scan(trees.getTree(rootElement), + treePath.getCompilationUnit()); + if (varScanner.getTrvElement() == null) { + throw new AssertionError("Element is null for 'trv'"); + } + } + } + return true; + } + + @Override + public void close() {} + + private void test1() { + // The resource variable "trv"'s Element is checked. + // Do not change the name of the variable. + try(TestResourceElement trv = this) {} + } + + class VariableScanner extends TreeScanner { + private Trees trees; + private Element trvElement; + + public VariableScanner(Trees trees) { + super(); + this.trees = trees; + } + @Override + public Void visitVariable(VariableTree node, CompilationUnitTree cu) { + // if this is "trv", get it's element. + if (node.getName().contentEquals("trv")) { + trvElement = trees.getElement(trees.getPath(cu, node)); + } + return super.visitVariable(node, cu); + } + + Element getTrvElement() { + return trvElement; + } + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } +} diff --git a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java index 45829b46e33..f240ba7f0ee 100644 --- a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java +++ b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java @@ -23,11 +23,11 @@ /* * @test - * @bug 6911256 6964740 + * @bug 6911256 6964740 6967842 * @summary Test that the resource variable kind is appropriately set * @author Joseph D. Darcy * @build TestResourceVariable - * @compile/fail -processor TestResourceVariable -proc:only TestResourceVariable.java + * @compile -processor TestResourceVariable -proc:only TestResourceVariable.java */ // Bug should be filed for this misbehavior From 836de5036ca296df721aa1ce93fe570bf97fa329 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Tue, 28 Sep 2010 10:57:56 -0700 Subject: [PATCH 49/88] 6915621: (rb) ResourceBundle.getBundle() deadlock when called inside a synchronized thread Reviewed-by: okutsu --- .../classes/java/util/ResourceBundle.java | 116 ++---------------- 1 file changed, 11 insertions(+), 105 deletions(-) diff --git a/jdk/src/share/classes/java/util/ResourceBundle.java b/jdk/src/share/classes/java/util/ResourceBundle.java index e645fe91439..9fbdbe1626d 100644 --- a/jdk/src/share/classes/java/util/ResourceBundle.java +++ b/jdk/src/share/classes/java/util/ResourceBundle.java @@ -292,16 +292,6 @@ public abstract class ResourceBundle { private static final ConcurrentMap cacheList = new ConcurrentHashMap(INITIAL_CACHE_SIZE); - /** - * This ConcurrentMap is used to keep multiple threads from loading the - * same bundle concurrently. The table entries are - * where CacheKey is the key for the bundle that is under construction - * and Thread is the thread that is constructing the bundle. - * This list is manipulated in findBundleInCache and putBundleInCache. - */ - private static final ConcurrentMap underConstruction - = new ConcurrentHashMap(); - /** * Queue for reference objects referring to class loaders or bundles. */ @@ -1381,7 +1371,7 @@ public abstract class ResourceBundle { boolean expiredBundle = false; // First, look up the cache to see if it's in the cache, without - // declaring beginLoading. + // attempting to load bundle. cacheKey.setLocale(targetLocale); ResourceBundle bundle = findBundleInCache(cacheKey, control); if (isValidBundle(bundle)) { @@ -1408,56 +1398,25 @@ public abstract class ResourceBundle { CacheKey constKey = (CacheKey) cacheKey.clone(); try { - // Try declaring loading. If beginLoading() returns true, - // then we can proceed. Otherwise, we need to take a look - // at the cache again to see if someone else has loaded - // the bundle and put it in the cache while we've been - // waiting for other loading work to complete. - while (!beginLoading(constKey)) { - bundle = findBundleInCache(cacheKey, control); - if (bundle == null) { - continue; - } - if (bundle == NONEXISTENT_BUNDLE) { - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist. - return parent; - } - expiredBundle = bundle.expired; - if (!expiredBundle) { - if (bundle.parent == parent) { - return bundle; - } - BundleReference bundleRef = cacheList.get(cacheKey); - if (bundleRef != null && bundleRef.get() == bundle) { - cacheList.remove(cacheKey, bundleRef); - } + bundle = loadBundle(cacheKey, formats, control, expiredBundle); + if (bundle != null) { + if (bundle.parent == null) { + bundle.setParent(parent); } + bundle.locale = targetLocale; + bundle = putBundleInCache(cacheKey, bundle, control); + return bundle; } - try { - bundle = loadBundle(cacheKey, formats, control, expiredBundle); - if (bundle != null) { - if (bundle.parent == null) { - bundle.setParent(parent); - } - bundle.locale = targetLocale; - bundle = putBundleInCache(cacheKey, bundle, control); - return bundle; - } - - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle - // instance for the locale. - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); - } finally { - endLoading(constKey); - } + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle + // instance for the locale. + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); } finally { if (constKey.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } - assert underConstruction.get(cacheKey) != Thread.currentThread(); return parent; } @@ -1465,7 +1424,6 @@ public abstract class ResourceBundle { List formats, Control control, boolean reload) { - assert underConstruction.get(cacheKey) == Thread.currentThread(); // Here we actually load the bundle in the order of formats // specified by the getFormats() value. @@ -1498,7 +1456,6 @@ public abstract class ResourceBundle { break; } } - assert underConstruction.get(cacheKey) == Thread.currentThread(); return bundle; } @@ -1529,57 +1486,6 @@ public abstract class ResourceBundle { return true; } - /** - * Declares the beginning of actual resource bundle loading. This method - * returns true if the declaration is successful and the current thread has - * been put in underConstruction. If someone else has already begun - * loading, this method waits until that loading work is complete and - * returns false. - */ - private static final boolean beginLoading(CacheKey constKey) { - Thread me = Thread.currentThread(); - Thread worker; - // We need to declare by putting the current Thread (me) to - // underConstruction that we are working on loading the specified - // resource bundle. If we are already working the loading, it means - // that the resource loading requires a recursive call. In that case, - // we have to proceed. (4300693) - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null) - || worker == me) { - return true; - } - - // If someone else is working on the loading, wait until - // the Thread finishes the bundle loading. - synchronized (worker) { - while (underConstruction.get(constKey) == worker) { - try { - worker.wait(); - } catch (InterruptedException e) { - // record the interruption - constKey.setCause(e); - } - } - } - return false; - } - - /** - * Declares the end of the bundle loading. This method calls notifyAll - * for those who are waiting for this completion. - */ - private static final void endLoading(CacheKey constKey) { - // Remove this Thread from the underConstruction map and wake up - // those who have been waiting for me to complete this bundle - // loading. - Thread me = Thread.currentThread(); - assert (underConstruction.get(constKey) == me); - underConstruction.remove(constKey); - synchronized (me) { - me.notifyAll(); - } - } - /** * Throw a MissingResourceException with proper message */ From 13069fe969cd05eeb68db64373c37eac681d3fd9 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Wed, 29 Sep 2010 10:44:02 +0400 Subject: [PATCH 50/88] 6735275: java.awt.image.SampleModel.getSamples() methods not allways throw ArrayIndexOutOfBoundsException Reviewed-by: igor, prr --- .../classes/java/awt/image/SampleModel.java | 36 +++++- jdk/test/java/awt/image/GetSamplesTest.java | 121 ++++++++++++++++++ 2 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 jdk/test/java/awt/image/GetSamplesTest.java diff --git a/jdk/src/share/classes/java/awt/image/SampleModel.java b/jdk/src/share/classes/java/awt/image/SampleModel.java index cb7bd8a491f..a2b02c44a62 100644 --- a/jdk/src/share/classes/java/awt/image/SampleModel.java +++ b/jdk/src/share/classes/java/awt/image/SampleModel.java @@ -937,14 +937,22 @@ public abstract class SampleModel int iArray[], DataBuffer data) { int pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates."); + } if (iArray != null) pixels = iArray; else pixels = new int[w * h]; - for(int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for(int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (fArray != null) pixels = fArray; else pixels = new float[w * h]; - for (int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for (int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (dArray != null) pixels = dArray; else pixels = new double[w * h]; - for (int i=y; i<(y+h); i++) { - for (int j=x; j<(x+w); j++) { + for (int i=y; i> classes = new Vector>(); + + classes.add(ComponentSampleModel.class); + classes.add(MultiPixelPackedSampleModel.class); + classes.add(SinglePixelPackedSampleModel.class); + classes.add(BandedSampleModel.class); + classes.add(PixelInterleavedSampleModel.class); + + for (Class c : classes) { + doTest(c); + } + } + private static void doTest(Class c) { + System.out.println("Test for: " + c.getName()); + SampleModel sm = createSampleModel(c); + + DataBuffer db = sm.createDataBuffer(); + + int[] iArray = new int[ width * height + numBands]; + float[] fArray = new float[ width * height + numBands]; + double[] dArray = new double[ width * height + numBands]; + + boolean iOk = false; + boolean fOk = false; + boolean dOk = false; + + try { + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + iOk = true; + } + + try { + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + fOk = true; + } + + try { + sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + dOk = true; + } + if (!iOk || !fOk || !dOk) { + throw new RuntimeException("Test for " + c.getSimpleName() + + " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk); + } + } + + private static SampleModel createSampleModel(Class cls) { + SampleModel res = null; + + if (cls == ComponentSampleModel.class) { + res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } ); + } else if (cls == MultiPixelPackedSampleModel.class) { + res = new MultiPixelPackedSampleModel(dataType, width, height, 4); + } else if (cls == SinglePixelPackedSampleModel.class) { + res = new SinglePixelPackedSampleModel(dataType, width, height, + new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }); + } else if (cls == BandedSampleModel.class) { + res = new BandedSampleModel(dataType, width, height, numBands); + } else if (cls == PixelInterleavedSampleModel.class) { + res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 }); + } else { + throw new RuntimeException("Unknown class " + cls); + } + return res; + } +} From b1bd74bb7d5bfdc262bee6b4ad2697701034603c Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 29 Sep 2010 15:26:59 +0800 Subject: [PATCH 51/88] 6988163: sun.security.util.Resources dup and a keytool doc typo Reviewed-by: xuelei --- .../classes/sun/security/tools/KeyTool.java | 2 +- .../classes/sun/security/util/Resources.java | 17 ++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java index 369fe600457..a3a102bfd47 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyTool.java +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java @@ -281,7 +281,7 @@ public final class KeyTool { RFC("rfc", null, "output in RFC style"), SIGALG("sigalg", "", "signature algorithm name"), SRCALIAS("srcalias", "", "source alias"), - SRCKEYPASS("srckeypass", "", "source keystore password"), + SRCKEYPASS("srckeypass", "", "source key password"), SRCKEYSTORE("srckeystore", "", "source keystore name"), SRCPROTECTED("srcprotected", null, "source keystore password protected"), SRCPROVIDERNAME("srcprovidername", "", "source keystore provider name"), diff --git a/jdk/src/share/classes/sun/security/util/Resources.java b/jdk/src/share/classes/sun/security/util/Resources.java index 8c57a60c80d..1186c298054 100644 --- a/jdk/src/share/classes/sun/security/util/Resources.java +++ b/jdk/src/share/classes/sun/security/util/Resources.java @@ -116,11 +116,9 @@ public class Resources extends java.util.ListResourceBundle { {"X.509 extension", "X.509 extension"}, //-ext {"output file name", - "output file name"}, //-file + "output file name"}, //-file and -outfile {"input file name", - "input file name"}, //-file - {"input file name", - "input file name"}, //-infile + "input file name"}, //-file and -infile {"key algorithm name", "key algorithm name"}, //-keyalg {"key password", @@ -133,8 +131,6 @@ public class Resources extends java.util.ListResourceBundle { "new password"}, //-new {"do not prompt", "do not prompt"}, //-noprompt - {"output file name", - "output file name"}, //-outfile {"password through protected mechanism", "password through protected mechanism"}, //-protected {"provider argument", @@ -151,8 +147,8 @@ public class Resources extends java.util.ListResourceBundle { "signature algorithm name"}, //-sigalg {"source alias", "source alias"}, //-srcalias - {"source keystore password", - "source keystore password"}, //-srckeypass + {"source key password", + "source key password"}, //-srckeypass {"source keystore name", "source keystore name"}, //-srckeystore {"source keystore password protected", @@ -276,8 +272,6 @@ public class Resources extends java.util.ListResourceBundle { "Alias <{0}> has no certificate"}, {"Key pair not generated, alias already exists", "Key pair not generated, alias <{0}> already exists"}, - {"Cannot derive signature algorithm", - "Cannot derive signature algorithm"}, {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name", "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"}, {"Enter key password for ", "Enter key password for <{0}>"}, @@ -321,8 +315,6 @@ public class Resources extends java.util.ListResourceBundle { {"Failed to parse input", "Failed to parse input"}, {"Empty input", "Empty input"}, {"Not X.509 certificate", "Not X.509 certificate"}, - {"Cannot derive signature algorithm", - "Cannot derive signature algorithm"}, {"alias has no public key", "{0} has no public key"}, {"alias has no X.509 certificate", "{0} has no X.509 certificate"}, {"New certificate (self-signed):", "New certificate (self-signed):"}, @@ -552,7 +544,6 @@ public class Resources extends java.util.ListResourceBundle { {"package name", "package name"}, {"policy type", "policy type"}, {"property name", "property name"}, - {"provider name", "provider name"}, {"Principal List", "Principal List"}, {"Permission List", "Permission List"}, {"Code Base", "Code Base"}, From 674e1ca1c7d411e8913ff3e18ac36bee861277dd Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Wed, 29 Sep 2010 17:33:17 +0100 Subject: [PATCH 52/88] 6987461: Handle leak when enabling java.net.useSystemProxies Release the registry key handle if ProxyEnable is 0 Reviewed-by: michaelm --- jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c b/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c index 5eb484e1735..5171024e41c 100644 --- a/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c +++ b/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c @@ -250,6 +250,10 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env, return proxy; } } + } else { + /* ProxyEnable == 0 or Query failed */ + /* close the handle to the registry key */ + RegCloseKey(hKey); } } From ef791d4adbade6c79d3372dbf524ab264da418a5 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 29 Sep 2010 14:01:37 -0700 Subject: [PATCH 53/88] 6502392: Invalid relative names for Filer.createResource and Filer.getResource Reviewed-by: darcy --- .../tools/javac/file/JavacFileManager.java | 10 +- .../filer/TestInvalidRelativeNames.java | 115 ++++++++++++++++++ 2 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 77ea25edf59..afa40d10d37 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -605,7 +605,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil nullCheck(className); nullCheck(kind); if (!sourceOrClass.contains(kind)) - throw new IllegalArgumentException("Invalid kind " + kind); + throw new IllegalArgumentException("Invalid kind: " + kind); return getFileForInput(location, RelativeFile.forClass(className, kind)); } @@ -658,7 +658,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil nullCheck(className); nullCheck(kind); if (!sourceOrClass.contains(kind)) - throw new IllegalArgumentException("Invalid kind " + kind); + throw new IllegalArgumentException("Invalid kind: " + kind); return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling); } @@ -672,7 +672,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil // validatePackageName(packageName); nullCheck(packageName); if (!isRelativeUri(relativeName)) - throw new IllegalArgumentException("relativeName is invalid"); + throw new IllegalArgumentException("Invalid relative name: " + relativeName); RelativeFile name = packageName.length() == 0 ? new RelativeFile(relativeName) : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName); @@ -806,6 +806,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil String path = uri.normalize().getPath(); if (path.length() == 0 /* isEmpty() is mustang API */) return false; + if (!path.equals(uri.getPath())) // implicitly checks for embedded . and .. + return false; char first = path.charAt(0); return first != '.' && first != '/'; } diff --git a/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java new file mode 100644 index 00000000000..5c8a7a5f2ab --- /dev/null +++ b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6502392 + * @summary Invalid relative names for Filer.createResource and Filer.getResource + * @compile TestInvalidRelativeNames.java + * @compile/process -processor TestInvalidRelativeNames java.lang.Object + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.Diagnostic; +import javax.tools.StandardLocation; + + +@SupportedAnnotationTypes("*") +public class TestInvalidRelativeNames extends AbstractProcessor { + enum Kind { CREATE_WRITER, GET_READER, CREATE_OUTPUT_STREAM, GET_INPUT_STREAM }; + + static final String[] invalidRelativeNames = { + "/boo", "goo/../hoo", "./ioo", "" + }; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + Filer filer; + Messager messager; + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + filer = processingEnv.getFiler(); + messager = processingEnv.getMessager(); + } + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + for (String relative: invalidRelativeNames) { + for (Kind kind: Kind.values()) { + test(relative, kind); + } + } + } + return true; + } + + void test(String relative, Kind kind) { + System.out.println("test relative path: " + relative + ", kind: " + kind); + try { + switch (kind) { + case CREATE_WRITER: + Writer writer = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openWriter(); + writer.close(); + break; + + case GET_READER: + Reader reader = filer.getResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openReader(true); + reader.close(); + break; + + case CREATE_OUTPUT_STREAM: + OutputStream out = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openOutputStream(); + out.close(); + break; + + case GET_INPUT_STREAM: + InputStream in = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openInputStream(); + in.close(); + break; + } + } catch (IllegalArgumentException expected) { + System.out.println("expected exception thrown: " + expected); + return; + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e); + return; + } + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", no exception thrown"); + } +} + From 4231c49495049595c7c011256ad1c38ff8a6ca45 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 29 Sep 2010 23:27:57 -0700 Subject: [PATCH 54/88] 6983738: Use a JavacTestingAbstractProcessor Reviewed-by: jjg --- .../lib/JavacTestingAbstractProcessor.java | 100 ++++++++++++++++++ .../tools/javac/processing/6348499/A.java | 10 +- .../javac/processing/6348499/T6348499.java | 6 +- .../javac/processing/6359313/T6359313.java | 6 +- .../javac/processing/6365040/ProcBar.java | 8 +- .../javac/processing/6365040/ProcFoo.java | 8 +- .../javac/processing/6365040/T6365040.java | 10 +- .../javac/processing/6413690/T6413690.java | 8 +- .../tools/javac/processing/6414633/A.java | 13 +-- .../javac/processing/6414633/T6414633.java | 8 +- .../javac/processing/6430209/T6430209.java | 7 +- .../javac/processing/6430209/b6341534.java | 24 ++--- .../processing/6499119/ClassProcessor.java | 12 +-- .../processing/6511613/DummyProcessor.java | 7 +- .../javac/processing/6511613/clss41701.java | 3 +- .../javac/processing/6512707/T6512707.java | 15 +-- .../javac/processing/6634138/T6634138.java | 17 +-- .../test/tools/javac/processing/T6439826.java | 5 +- .../test/tools/javac/processing/T6920317.java | 8 +- .../environment/TestSourceVersion.java | 12 +-- .../round/TestElementsAnnotatedWith.java | 20 ++-- .../errors/TestFatalityOfParseErrors.java | 20 +--- .../errors/TestOptionSyntaxErrors.java | 11 +- .../processing/errors/TestReturnCode.java | 15 +-- .../filer/TestFilerConstraints.java | 19 +--- .../processing/filer/TestGetResource.java | 23 +--- .../processing/filer/TestGetResource2.java | 18 ++-- .../filer/TestInvalidRelativeNames.java | 21 +--- .../javac/processing/filer/TestLastRound.java | 11 +- .../processing/filer/TestPackageInfo.java | 30 +----- .../processing/messager/6362067/T6362067.java | 33 +++--- .../processing/messager/MessagerBasics.java | 14 +-- .../processing/model/6194785/T6194785.java | 9 +- .../processing/model/6341534/T6341534.java | 19 ++-- .../model/element/TestAnonClassNames.java | 10 +- .../model/element/TestAnonSourceNames.java | 8 +- .../processing/model/element/TestElement.java | 13 +-- .../processing/model/element/TestNames.java | 20 +--- .../model/element/TestPackageElement.java | 22 +--- .../model/element/TestResourceElement.java | 11 +- .../model/element/TestResourceVariable.java | 11 +- .../model/element/TypeParamBounds.java | 24 +---- .../model/type/MirroredTypeEx/OverEager.java | 21 +--- .../model/type/MirroredTypeEx/Plurality.java | 21 +--- .../javac/processing/model/type/NoTypes.java | 22 +--- .../processing/model/util/BinaryName.java | 16 +-- .../model/util/GetTypeElemBadArg.java | 22 +--- .../javac/processing/model/util/NoSupers.java | 16 +-- .../model/util/OverridesSpecEx.java | 25 +---- .../processing/model/util/TypesBadArg.java | 13 +-- .../util/deprecation/TestDeprecation.java | 12 +-- .../directSupersOfErr/DirectSupersOfErr.java | 16 +-- .../elements/TestGetConstantExpression.java | 20 +--- .../model/util/elements/TestGetPackageOf.java | 19 +--- .../model/util/filter/TestIterables.java | 15 +-- .../warnings/TestSourceVersionWarnings.java | 5 +- .../javac/processing/werror/WError1.java | 11 +- .../javac/processing/werror/WErrorGen.java | 11 +- .../javac/processing/werror/WErrorLast.java | 11 +- 59 files changed, 330 insertions(+), 615 deletions(-) create mode 100644 langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java diff --git a/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java new file mode 100644 index 00000000000..2706782b10d --- /dev/null +++ b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import static javax.lang.model.SourceVersion.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; + +/** + * An abstract annotation processor tailored to javac regression testing. + */ +public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { + private static final Set allAnnotations; + + static { + Set tmp = new HashSet<>(); + tmp.add("*"); + allAnnotations = Collections.unmodifiableSet(tmp); + } + + protected Elements eltUtils; + protected Elements elements; + protected Types typeUtils; + protected Types types; + protected Filer filer; + protected Messager messager; + protected Map options; + + /** + * Constructor for subclasses to call. + */ + protected JavacTestingAbstractProcessor() { + super(); + } + + /** + * Return the latest source version. Unless this method is + * overridden, an {@code IllegalStateException} will be thrown if a + * subclass has a {@code SupportedSourceVersion} annotation. + */ + @Override + public SourceVersion getSupportedSourceVersion() { + SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class); + if (ssv != null) + throw new IllegalStateException("SupportedSourceVersion annotation not supported here."); + + return SourceVersion.latest(); + } + + /** + * If the processor class is annotated with {@link + * SupportedAnnotationTypes}, return an unmodifiable set with the + * same set of strings as the annotation. If the class is not so + * annotated, a one-element set containing {@code "*"} is returned + * to indicate all annotations are processed. + * + * @return the names of the annotation types supported by this + * processor, or an empty set if none + */ + @Override + public Set getSupportedAnnotationTypes() { + SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class); + if (sat != null) + return super.getSupportedAnnotationTypes(); + else + return allAnnotations; + } + + @Override + public void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + elements = eltUtils = processingEnv.getElementUtils(); + types = typeUtils = processingEnv.getTypeUtils(); + filer = processingEnv.getFiler(); + messager = processingEnv.getMessager(); + options = processingEnv.getOptions(); + } +} diff --git a/langtools/test/tools/javac/processing/6348499/A.java b/langtools/test/tools/javac/processing/6348499/A.java index 9bdafaee3e2..b5b3aaf37f2 100644 --- a/langtools/test/tools/javac/processing/6348499/A.java +++ b/langtools/test/tools/javac/processing/6348499/A.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,8 @@ import javax.annotation.processing.*; import javax.lang.model.*; import javax.lang.model.element.*; -@SupportedAnnotationTypes("*") -public class A extends AbstractProcessor { +public class A extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment renv) { - Filer filer = processingEnv.getFiler(); try { OutputStream out = filer.createClassFile(getClass().getName()+"_0").openOutputStream(); out.close(); @@ -39,8 +37,4 @@ public class A extends AbstractProcessor { } return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/6348499/T6348499.java b/langtools/test/tools/javac/processing/6348499/T6348499.java index e558cc12972..25e2a07a03f 100644 --- a/langtools/test/tools/javac/processing/6348499/T6348499.java +++ b/langtools/test/tools/javac/processing/6348499/T6348499.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ * @test * @bug 6441871 * @summary javac crashes at com.sun.tools.javac.jvm.ClassReader$BadClassFile - * @build A + * @library ../../lib + * @build JavacTestingAbstractProcessor A * @run main T6348499 */ @@ -54,7 +55,6 @@ public class T6348499 { fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); Iterable opts = Arrays.asList("-proc:only", "-processor", "A", - "-source", "1.6", "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); diff --git a/langtools/test/tools/javac/processing/6359313/T6359313.java b/langtools/test/tools/javac/processing/6359313/T6359313.java index 025a4821a00..719ea12ff12 100644 --- a/langtools/test/tools/javac/processing/6359313/T6359313.java +++ b/langtools/test/tools/javac/processing/6359313/T6359313.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6359313 * @summary error compiling annotated package * @author Peter von der Ah\u00e9 + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6359313.java * @compile -processor T6359313 package-info.java Foo.java */ @@ -37,7 +39,7 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.TypeElement; @SupportedAnnotationTypes("Foo") -public class T6359313 extends AbstractProcessor { +public class T6359313 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { return true; diff --git a/langtools/test/tools/javac/processing/6365040/ProcBar.java b/langtools/test/tools/javac/processing/6365040/ProcBar.java index 1fd93bc6acb..3241692b08d 100644 --- a/langtools/test/tools/javac/processing/6365040/ProcBar.java +++ b/langtools/test/tools/javac/processing/6365040/ProcBar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,13 +31,11 @@ import static javax.tools.Diagnostic.Kind.*; /** * Second of several processors to run. */ -@SupportedAnnotationTypes("*") -public class ProcBar extends AbstractProcessor { +public class ProcBar extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from ProcBar"); + messager.printMessage(NOTE, "Hello from ProcBar"); return false; } } diff --git a/langtools/test/tools/javac/processing/6365040/ProcFoo.java b/langtools/test/tools/javac/processing/6365040/ProcFoo.java index f86d0ddbec1..14cdec25ade 100644 --- a/langtools/test/tools/javac/processing/6365040/ProcFoo.java +++ b/langtools/test/tools/javac/processing/6365040/ProcFoo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,13 +31,11 @@ import static javax.tools.Diagnostic.Kind.*; /** * First of several processors to run. */ -@SupportedAnnotationTypes("*") -public class ProcFoo extends AbstractProcessor { +public class ProcFoo extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from ProcFoo"); + messager.printMessage(NOTE, "Hello from ProcFoo"); return false; } } diff --git a/langtools/test/tools/javac/processing/6365040/T6365040.java b/langtools/test/tools/javac/processing/6365040/T6365040.java index 5215459bee7..0b1e0dc851c 100644 --- a/langtools/test/tools/javac/processing/6365040/T6365040.java +++ b/langtools/test/tools/javac/processing/6365040/T6365040.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6365040 6358129 * @summary Test -processor foo,bar,baz * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile ProcFoo.java * @compile ProcBar.java * @compile T6365040.java @@ -43,13 +45,11 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.TypeElement; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6365040 extends AbstractProcessor { +public class T6365040 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from T6365040"); + messager.printMessage(NOTE, "Hello from T6365040"); return true; } } diff --git a/langtools/test/tools/javac/processing/6413690/T6413690.java b/langtools/test/tools/javac/processing/6413690/T6413690.java index c51586263ab..a4b2b3fab33 100644 --- a/langtools/test/tools/javac/processing/6413690/T6413690.java +++ b/langtools/test/tools/javac/processing/6413690/T6413690.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6413690 6380018 * @summary JavacProcessingEnvironment does not enter trees from preceding rounds * @author Peter von der Ah\u00e9 + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6413690.java * @compile -XDfatalEnterError -verbose -processor T6413690 src/Super.java TestMe.java */ @@ -42,11 +44,9 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; @SupportedAnnotationTypes("TestMe") -public class T6413690 extends AbstractProcessor { +public class T6413690 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - Elements elements = processingEnv.getElementUtils(); - Filer filer = processingEnv.getFiler(); TypeElement testMe = elements.getTypeElement(TestMe.class.getName()); Set supers = roundEnvironment.getElementsAnnotatedWith(testMe); try { diff --git a/langtools/test/tools/javac/processing/6414633/A.java b/langtools/test/tools/javac/processing/6414633/A.java index 814106a7aef..13754d09cbe 100644 --- a/langtools/test/tools/javac/processing/6414633/A.java +++ b/langtools/test/tools/javac/processing/6414633/A.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,8 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class A extends AbstractProcessor { - +@SuppressWarnings("") +public class A extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { Messager m = processingEnv.getMessager(); for (TypeElement anno: annotations) { @@ -42,8 +41,6 @@ public class A extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } + @SuppressWarnings("") + private void foo() {} } diff --git a/langtools/test/tools/javac/processing/6414633/T6414633.java b/langtools/test/tools/javac/processing/6414633/T6414633.java index 29ef3caf599..0ae395153cb 100644 --- a/langtools/test/tools/javac/processing/6414633/T6414633.java +++ b/langtools/test/tools/javac/processing/6414633/T6414633.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ * @test * @bug 6414633 6440109 * @summary Only the first processor message at a source location is reported - * @build A T6414633 + * @library ../../lib + * @build JavacTestingAbstractProcessor A T6414633 * @run main T6414633 */ @@ -55,8 +56,7 @@ public class T6414633 { fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java"))); String[] opts = { "-proc:only", "-processor", A.class.getName(), - "-source", "1.6", - "-classpath", testClasses }; + "-classpath", testClasses + System.getProperty("path.separator") + "../../lib" }; JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); task.call(); diff --git a/langtools/test/tools/javac/processing/6430209/T6430209.java b/langtools/test/tools/javac/processing/6430209/T6430209.java index 69b7bf5d294..0f65f86be07 100644 --- a/langtools/test/tools/javac/processing/6430209/T6430209.java +++ b/langtools/test/tools/javac/processing/6430209/T6430209.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ * @test * @bug 6441871 * @summary spurious compiler error elicited by packageElement.getEnclosedElements() - * @build b6341534 + * @library ../../lib + * @build JavacTestingAbstractProcessor b6341534 * @run main T6430209 */ @@ -54,7 +55,7 @@ public class T6430209 { // run annotation processor b6341534 so we can check diagnostics // -proc:only -processor b6341534 -cp . ./src/*.java String testSrc = System.getProperty("test.src", "."); - String testClasses = System.getProperty("test.classes"); + String testClasses = System.getProperty("test.classes") + System.getProperty("path.separator") + "../../lib"; JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); diff --git a/langtools/test/tools/javac/processing/6430209/b6341534.java b/langtools/test/tools/javac/processing/6430209/b6341534.java index cc52af24a39..5dfad046c90 100644 --- a/langtools/test/tools/javac/processing/6430209/b6341534.java +++ b/langtools/test/tools/javac/processing/6430209/b6341534.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,16 +30,9 @@ import static javax.tools.Diagnostic.Kind.*; import java.util.*; import java.util.Set; -@SupportedAnnotationTypes({"*"}) -public class b6341534 extends AbstractProcessor { +public class b6341534 extends JavacTestingAbstractProcessor { static int r = 0; - static Elements E = null; - static Messager msgr = null; - public void init(ProcessingEnvironment penv) { - processingEnv = penv; - msgr = penv.getMessager(); - E = penv.getElementUtils(); - } + //Create directory 'dir1' and a test class in dir1 public boolean process(Set tes, RoundEnvironment renv) { @@ -49,13 +42,13 @@ public class b6341534 extends AbstractProcessor { System.out.println("Round"+r+ ": " + t.toString()); try { - PackageElement PE = E.getPackageElement("dir1"); + PackageElement PE = eltUtils.getPackageElement("dir1"); List LEE = PE.getEnclosedElements(); /* <=This line elicits the error message. */ for(Element e : LEE) System.out.println("found " + e.toString() + " in dir1."); } catch(NullPointerException npe) { - msgr.printMessage(ERROR,npe.toString()); + messager.printMessage(ERROR,npe.toString()); //npe.printStackTrace(); return false; } @@ -63,13 +56,8 @@ public class b6341534 extends AbstractProcessor { // on round 1, expect errorRaised == false && processingOver == false // on round 2, expect errorRaised == true && processingOver == true if( renv.errorRaised() != renv.processingOver()) { - msgr.printMessage(ERROR, "FAILED"); + messager.printMessage(ERROR, "FAILED"); } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/6499119/ClassProcessor.java b/langtools/test/tools/javac/processing/6499119/ClassProcessor.java index 900474e8460..b2b7203c0e7 100644 --- a/langtools/test/tools/javac/processing/6499119/ClassProcessor.java +++ b/langtools/test/tools/javac/processing/6499119/ClassProcessor.java @@ -32,20 +32,17 @@ import javax.tools.Diagnostic.Kind; * @test * @bug 6499119 * @summary Created package-info class file modeled improperly + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile ClassProcessor.java package-info.java * @compile/process -cp . -processor ClassProcessor -Akind=java java.lang.Object * @compile/process -cp . -processor ClassProcessor -Akind=class java.lang.Object */ @SupportedOptions({ "gen", "expect" }) -@SupportedAnnotationTypes({"*"}) -public class ClassProcessor extends AbstractProcessor { +public class ClassProcessor extends JavacTestingAbstractProcessor { int round = 1; - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (round == 1) { System.out.println("-- Round 1 --"); @@ -71,8 +68,6 @@ public class ClassProcessor extends AbstractProcessor { } private void createPackageFile() { - Filer filer = processingEnv.getFiler(); - String kind = processingEnv.getOptions().get("kind"); File pkgInfo; @@ -125,7 +120,6 @@ public class ClassProcessor extends AbstractProcessor { } private void error(String msg) { - Messager messager = processingEnv.getMessager(); messager.printMessage(Kind.ERROR, msg); } } diff --git a/langtools/test/tools/javac/processing/6511613/DummyProcessor.java b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java index a5307f2f1ca..c05537ed6ec 100644 --- a/langtools/test/tools/javac/processing/6511613/DummyProcessor.java +++ b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java @@ -26,15 +26,10 @@ import javax.lang.model.*; import javax.lang.model.element.*; import java.util.Set; -@SupportedAnnotationTypes("*") -public class DummyProcessor extends AbstractProcessor { +public class DummyProcessor extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/6511613/clss41701.java b/langtools/test/tools/javac/processing/6511613/clss41701.java index 1d5c7819f2e..670ae5e269f 100644 --- a/langtools/test/tools/javac/processing/6511613/clss41701.java +++ b/langtools/test/tools/javac/processing/6511613/clss41701.java @@ -26,7 +26,8 @@ * @bug 6511613 * @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified * - * @build DummyProcessor + * @library ../../lib + * @build JavacTestingAbstractProcessor DummyProcessor * @compile/fail clss41701.java * @compile/fail -processor DummyProcessor clss41701.java */ diff --git a/langtools/test/tools/javac/processing/6512707/T6512707.java b/langtools/test/tools/javac/processing/6512707/T6512707.java index 505528fd8ee..26c72f9ff95 100644 --- a/langtools/test/tools/javac/processing/6512707/T6512707.java +++ b/langtools/test/tools/javac/processing/6512707/T6512707.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,9 @@ * @bug 6512707 * @summary "incompatible types" after (unrelated) annotation processing * @author Peter Runge + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6512707.java - * * @compile -processor T6512707 TestAnnotation.java */ @@ -41,16 +42,10 @@ import javax.lang.model.util.*; * Dummy processor to force bug 6512707 to show - it does not matter what * the annotation processor does for this bug. */ -@SupportedAnnotationTypes("*") -public class T6512707 extends AbstractProcessor { +public class T6512707 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { - return(false); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); + return false; } } diff --git a/langtools/test/tools/javac/processing/6634138/T6634138.java b/langtools/test/tools/javac/processing/6634138/T6634138.java index c7ce94b6e26..54409e5ecb4 100644 --- a/langtools/test/tools/javac/processing/6634138/T6634138.java +++ b/langtools/test/tools/javac/processing/6634138/T6634138.java @@ -26,6 +26,8 @@ * @bug 6634138 * @author Joseph D. Darcy * @summary Verify source files output after processing is over are compiled + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6634138.java * @compile -processor T6634138 Dummy.java * @run main ExerciseDependency @@ -44,10 +46,7 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class T6634138 extends AbstractProcessor { - private Filer filer; - +public class T6634138 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { // Write out files *after* processing is over. @@ -77,16 +76,6 @@ public class T6634138 extends AbstractProcessor { } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - } } diff --git a/langtools/test/tools/javac/processing/T6439826.java b/langtools/test/tools/javac/processing/T6439826.java index 91c36aeed51..ac484655f37 100644 --- a/langtools/test/tools/javac/processing/T6439826.java +++ b/langtools/test/tools/javac/processing/T6439826.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,8 +48,7 @@ public class T6439826 extends AbstractProcessor { StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java"))); - Iterable opts = Arrays.asList("-source","1.6", - "-proc:only", + Iterable opts = Arrays.asList("-proc:only", "-processor", "T6439826", "-processorpath", testClasses); StringWriter out = new StringWriter(); diff --git a/langtools/test/tools/javac/processing/T6920317.java b/langtools/test/tools/javac/processing/T6920317.java index 981607cf01c..1f005090361 100644 --- a/langtools/test/tools/javac/processing/T6920317.java +++ b/langtools/test/tools/javac/processing/T6920317.java @@ -25,6 +25,7 @@ * @test * @bug 6920317 * @summary package-info.java file has to be specified on the javac cmdline, else it will not be avail + * @library ../lib */ import java.io.*; @@ -349,12 +350,7 @@ public class T6920317 { /** Annotation processor used to verify the expected value for the package annotations found by javac. */ @SupportedOptions({ "gen", "expect" }) - @SupportedAnnotationTypes({"*"}) - public static class Processor extends AbstractProcessor { - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - + public static class Processor extends JavacTestingAbstractProcessor { public boolean process(Set annots, RoundEnvironment renv) { round++; System.err.println("Round " + round + " annots:" + annots + " rootElems:" + renv.getRootElements()); diff --git a/langtools/test/tools/javac/processing/environment/TestSourceVersion.java b/langtools/test/tools/javac/processing/environment/TestSourceVersion.java index dc3e7773a03..28118bb7e0a 100644 --- a/langtools/test/tools/javac/processing/environment/TestSourceVersion.java +++ b/langtools/test/tools/javac/processing/environment/TestSourceVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6402506 * @summary Test that getSourceVersion works properly * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestSourceVersion.java * @compile -processor TestSourceVersion -proc:only -source 1.2 -AExpectedVersion=RELEASE_2 HelloWorld.java * @compile -processor TestSourceVersion -proc:only -source 1.3 -AExpectedVersion=RELEASE_3 HelloWorld.java @@ -52,9 +54,8 @@ import static javax.tools.Diagnostic.Kind.*; * This processor checks that ProcessingEnvironment.getSourceVersion() * is consistent with the setting of the -source option. */ -@SupportedAnnotationTypes("*") @SupportedOptions("ExpectedVersion") -public class TestSourceVersion extends AbstractProcessor { +public class TestSourceVersion extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { @@ -68,9 +69,4 @@ public class TestSourceVersion extends AbstractProcessor { return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java index 22b180ad085..0bf241b8e80 100644 --- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java +++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 * @summary Tests that getElementsAnnotatedWith works properly. * @author Joseph D. Darcy + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile TestElementsAnnotatedWith.java * @compile InheritedAnnotation.java * @compile -processor TestElementsAnnotatedWith -proc:only SurfaceAnnotations.java @@ -57,16 +59,13 @@ import static javax.lang.model.util.ElementFilter.*; * getElementsAnnotatedWith is consistent with the expected results * stored in an AnnotatedElementInfo annotation. */ -@SupportedAnnotationTypes("*") @AnnotatedElementInfo(annotationName="java.lang.SuppressWarnings", expectedSize=0, names={}) -public class TestElementsAnnotatedWith extends AbstractProcessor { +public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - Elements elementUtils = processingEnv.getElementUtils(); - TypeElement annotatedElementInfoElement = - elementUtils.getTypeElement("AnnotatedElementInfo"); + elements.getTypeElement("AnnotatedElementInfo"); Set resultsMeta = Collections.emptySet(); Set resultsBase = Collections.emptySet(); @@ -93,9 +92,7 @@ public class TestElementsAnnotatedWith extends AbstractProcessor { resultsMeta = roundEnvironment. - getElementsAnnotatedWith(elementUtils. - getTypeElement(annotatedElementInfo. - annotationName())) ; + getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName())); System.err.println("Results: " + resultsMeta); @@ -167,9 +164,4 @@ public class TestElementsAnnotatedWith extends AbstractProcessor { throw new RuntimeException("Illegal argument exception not thrown"); } catch(IllegalArgumentException iae) {} } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java b/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java index 0ba614d4274..cd42f6bd06a 100644 --- a/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java +++ b/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,9 @@ * @bug 6403459 * @summary Test that generating programs with syntax errors is a fatal condition * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor + * @compile TestReturnCode.java * @compile TestFatalityOfParseErrors.java * @compile/fail -XprintRounds -processor TestFatalityOfParseErrors -proc:only TestFatalityOfParseErrors.java */ @@ -45,11 +48,8 @@ import java.io.IOException; * Write out an incomplete source file and observe that the next round * is marked as an error. */ -@SupportedAnnotationTypes("*") -public class TestFatalityOfParseErrors extends AbstractProcessor { +public class TestFatalityOfParseErrors extends JavacTestingAbstractProcessor { int round = 0; - Messager messager; - Filer filer; public boolean process(Set annotations, RoundEnvironment roundEnvironment) { @@ -87,14 +87,4 @@ public class TestFatalityOfParseErrors extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - } } diff --git a/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java b/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java index 6784def2cd5..4f2ad1b2243 100644 --- a/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java +++ b/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6406212 * @summary Test that annotation processor options with illegal syntax are rejected * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestOptionSyntaxErrors.java * @compile/fail -A TestOptionSyntaxErrors.java * @compile/fail -A8adOption TestOptionSyntaxErrors.java @@ -46,14 +48,9 @@ import static javax.tools.Diagnostic.Kind.*; /** * No-op processor; should not be run. */ -@SupportedAnnotationTypes("*") -public class TestOptionSyntaxErrors extends AbstractProcessor { +public class TestOptionSyntaxErrors extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/errors/TestReturnCode.java b/langtools/test/tools/javac/processing/errors/TestReturnCode.java index 61cb2a05b72..22c9aae24f7 100644 --- a/langtools/test/tools/javac/processing/errors/TestReturnCode.java +++ b/langtools/test/tools/javac/processing/errors/TestReturnCode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6403468 * @summary Test that an erroneous return code results from raising an error. * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestReturnCode.java * * @compile -processor TestReturnCode -proc:only Foo.java @@ -60,20 +62,17 @@ import static javax.tools.Diagnostic.Kind.*; * This processor raises errors or throws exceptions on different * rounds to allow the return code to be test. */ -@SupportedAnnotationTypes("*") @SupportedOptions({"ErrorOnFirst", "ErrorOnLast", "ExceptionOnFirst", "ExceptionOnLast"}) -public class TestReturnCode extends AbstractProcessor { +public class TestReturnCode extends JavacTestingAbstractProcessor { private boolean errorOnFirst; private boolean errorOnLast; private boolean exceptionOnFirst; private boolean exceptionOnLast; - private Messager messager; - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -103,11 +102,5 @@ public class TestReturnCode extends AbstractProcessor { errorOnLast = keySet.contains("ErrorOnLast"); exceptionOnFirst = keySet.contains("ExceptionOnFirst"); exceptionOnLast = keySet.contains("ExceptionOnLast"); - messager = processingEnv.getMessager(); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); } } diff --git a/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java b/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java index 7f3202eca30..8509fb2e15a 100644 --- a/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java +++ b/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ * @bug 6380018 6453386 6457283 * @summary Test that the constraints guaranteed by the Filer and maintained * @author Joseph D. Darcy + * @library ../../lib * @build TestFilerConstraints * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java */ @@ -69,11 +70,8 @@ import java.nio.charset.Charset; * * */ -@SupportedAnnotationTypes("*") -public class TestFilerConstraints extends AbstractProcessor { +public class TestFilerConstraints extends JavacTestingAbstractProcessor { private int round = 0; - private Messager messager; - private Filer filer; private PrintWriter pw_src1 = null; private PrintWriter pw_src2 = null; @@ -167,17 +165,6 @@ public class TestFilerConstraints extends AbstractProcessor { return true; } - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - - } - /** * Test that the single expected expected type, name, is the root * element. diff --git a/langtools/test/tools/javac/processing/filer/TestGetResource.java b/langtools/test/tools/javac/processing/filer/TestGetResource.java index ee55a1a4389..5d5641214e1 100644 --- a/langtools/test/tools/javac/processing/filer/TestGetResource.java +++ b/langtools/test/tools/javac/processing/filer/TestGetResource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6380018 6449798 * @summary Test Filer.getResource * @author Joseph D. Darcy - * @build TestGetResource + * @library ../../lib + * @build JavacTestingAbstractProcessor TestGetResource * @compile -processor TestGetResource -proc:only -Aphase=write TestGetResource.java * @compile -processor TestGetResource -proc:only -Aphase=read TestGetResource.java */ @@ -49,13 +50,8 @@ import java.io.PrintWriter; * first run of the annotation processor, write out a resource file * and on the second run read it in. */ -@SupportedAnnotationTypes("*") @SupportedOptions("phase") -public class TestGetResource extends AbstractProcessor { - private Messager messager; - private Filer filer; - private Map options; - +public class TestGetResource extends JavacTestingAbstractProcessor { private static String CONTENTS = "Hello World."; private static String PKG = ""; private static String RESOURCE_NAME = "Resource1"; @@ -92,15 +88,4 @@ public class TestGetResource extends AbstractProcessor { } return false; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - options = processingEnv.getOptions(); - } } diff --git a/langtools/test/tools/javac/processing/filer/TestGetResource2.java b/langtools/test/tools/javac/processing/filer/TestGetResource2.java index 49befdf4e34..6ce067d4c31 100644 --- a/langtools/test/tools/javac/processing/filer/TestGetResource2.java +++ b/langtools/test/tools/javac/processing/filer/TestGetResource2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ /* @test * @bug 6929404 * @summary Filer.getResource(SOURCE_PATH, ...) does not work when -sourcepath contains >1 entry + * @library ../../lib */ import java.io.*; @@ -114,8 +115,7 @@ public class TestGetResource2 { throw new Exception(errors + " errors occurred"); } - @SupportedAnnotationTypes("*") - static class AnnoProc extends AbstractProcessor { + static class AnnoProc extends JavacTestingAbstractProcessor { public @Override boolean process(Set annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { @@ -123,27 +123,23 @@ public class TestGetResource2 { } try { - FileObject resource = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt"); + FileObject resource = filer.getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt"); try { resource.openInputStream().close(); - processingEnv.getMessager().printMessage(Kind.NOTE, "found: " + resource.toUri()); + messager.printMessage(Kind.NOTE, "found: " + resource.toUri()); return true; } catch (IOException x) { - processingEnv.getMessager().printMessage(Kind.ERROR, "could not read: " + resource.toUri()); + messager.printMessage(Kind.ERROR, "could not read: " + resource.toUri()); x.printStackTrace(); } } catch (IOException x) { - processingEnv.getMessager().printMessage(Kind.ERROR, "did not find resource"); + messager.printMessage(Kind.ERROR, "did not find resource"); x.printStackTrace(); } return false; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } private File write(File dir, String path, String contents) throws IOException { diff --git a/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java index 5c8a7a5f2ab..4a0efd53560 100644 --- a/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java +++ b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java @@ -25,6 +25,8 @@ * @test * @bug 6502392 * @summary Invalid relative names for Filer.createResource and Filer.getResource + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestInvalidRelativeNames.java * @compile/process -processor TestInvalidRelativeNames java.lang.Object */ @@ -37,30 +39,13 @@ import javax.lang.model.element.*; import javax.tools.Diagnostic; import javax.tools.StandardLocation; - -@SupportedAnnotationTypes("*") -public class TestInvalidRelativeNames extends AbstractProcessor { +public class TestInvalidRelativeNames extends JavacTestingAbstractProcessor { enum Kind { CREATE_WRITER, GET_READER, CREATE_OUTPUT_STREAM, GET_INPUT_STREAM }; static final String[] invalidRelativeNames = { "/boo", "goo/../hoo", "./ioo", "" }; - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - Filer filer; - Messager messager; - - @Override - public void init(ProcessingEnvironment pEnv) { - super.init(pEnv); - filer = processingEnv.getFiler(); - messager = processingEnv.getMessager(); - } - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { for (String relative: invalidRelativeNames) { diff --git a/langtools/test/tools/javac/processing/filer/TestLastRound.java b/langtools/test/tools/javac/processing/filer/TestLastRound.java index efef9e15ec0..57c76af78e7 100644 --- a/langtools/test/tools/javac/processing/filer/TestLastRound.java +++ b/langtools/test/tools/javac/processing/filer/TestLastRound.java @@ -24,6 +24,8 @@ /* * @test 6966604 * @summary JavacFiler not correctly notified of lastRound + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestLastRound.java * @compile/fail/ref=TestLastRound.out -XDrawDiagnostics -Werror -proc:only -processor TestLastRound TestLastRound.java */ @@ -35,12 +37,10 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class TestLastRound extends AbstractProcessor { +public class TestLastRound extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Filer filer = processingEnv.getFiler(); if (roundEnv.processingOver()) { try { JavaFileObject fo = filer.createSourceFile("LastRound.java"); @@ -52,9 +52,4 @@ public class TestLastRound extends AbstractProcessor { } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java index 2e7ae10521c..7a905467370 100644 --- a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java +++ b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6380018 6392177 * @summary Test the ability to create and process package-info.java files * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestPackageInfo.java * @compile -processor TestPackageInfo -proc:only foo/bar/package-info.java TestPackageInfo.java */ @@ -49,13 +51,7 @@ import java.io.*; * 1) Visibility of package-info files from the command line * 2) Visibility of generated package-info.java source files */ -@SupportedAnnotationTypes("*") -public class TestPackageInfo extends AbstractProcessor { - private Elements eltUtils; - private Messager messager; - private Filer filer; - private Map options; - +public class TestPackageInfo extends JavacTestingAbstractProcessor { private int round = 0; public boolean process(Set annotations, @@ -64,11 +60,7 @@ public class TestPackageInfo extends AbstractProcessor { // Verify annotations are as expected Set expectedAnnotations = new HashSet(); - if (round == 1) - expectedAnnotations.add(eltUtils. - getTypeElement("javax.annotation.processing.SupportedAnnotationTypes")); - expectedAnnotations.add(eltUtils. - getTypeElement("java.lang.SuppressWarnings")); + expectedAnnotations.add(eltUtils.getTypeElement("java.lang.SuppressWarnings")); if (!roundEnv.processingOver()) { System.out.println("\nRound " + round); @@ -127,16 +119,4 @@ public class TestPackageInfo extends AbstractProcessor { } return false; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - options = processingEnv.getOptions(); - } } diff --git a/langtools/test/tools/javac/processing/messager/6362067/T6362067.java b/langtools/test/tools/javac/processing/messager/6362067/T6362067.java index ce5bd8d0bed..ef2cec88d28 100644 --- a/langtools/test/tools/javac/processing/messager/6362067/T6362067.java +++ b/langtools/test/tools/javac/processing/messager/6362067/T6362067.java @@ -2,39 +2,34 @@ * @test /nodynamiccopyright/ * @bug 6362067 * @summary Messager methods do not print out source position information - * @build T6362067 + * @library ../../../lib + * @build JavacTestingAbstractProcessor T6362067 * @compile -processor T6362067 -proc:only T6362067.java * @compile/ref=T6362067.out -XDrawDiagnostics -processor T6362067 -proc:only T6362067.java */ - import java.util.Set; import javax.annotation.processing.*; import javax.lang.model.element.*; import static javax.tools.Diagnostic.Kind.*; -@Deprecated // convenient test annotation -@SupportedAnnotationTypes("*") -public class T6362067 extends AbstractProcessor { +@Deprecated // convenient test annotations +@SuppressWarnings({""}) +public class T6362067 extends JavacTestingAbstractProcessor { public boolean process(Set annos, RoundEnvironment roundEnv) { - Messager msgr = processingEnv.getMessager(); - for (Element e: roundEnv.getRootElements()) { - msgr.printMessage(NOTE, "note:elem", e); - for (AnnotationMirror a: e.getAnnotationMirrors()) { - msgr.printMessage(NOTE, "note:anno", e, a); - for (AnnotationValue v: a.getElementValues().values()) { - msgr.printMessage(NOTE, "note:value", e, a, v); - } + for (Element e: roundEnv.getRootElements()) { + messager.printMessage(NOTE, "note:elem", e); + for (AnnotationMirror a: e.getAnnotationMirrors()) { + messager.printMessage(NOTE, "note:anno", e, a); + for (AnnotationValue v: a.getElementValues().values()) { + messager.printMessage(NOTE, "note:value", e, a, v); + } } } + if (roundEnv.processingOver()) - msgr.printMessage(NOTE, "note:nopos"); + messager.printMessage(NOTE, "note:nopos"); return true; } - - @Override - public javax.lang.model.SourceVersion getSupportedSourceVersion() { - return javax.lang.model.SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/messager/MessagerBasics.java b/langtools/test/tools/javac/processing/messager/MessagerBasics.java index cbcbf094a42..f7980c70109 100644 --- a/langtools/test/tools/javac/processing/messager/MessagerBasics.java +++ b/langtools/test/tools/javac/processing/messager/MessagerBasics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6341173 6341072 * @summary Test presence of Messager methods * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile MessagerBasics.java * @compile -processor MessagerBasics -proc:only MessagerBasics.java * @compile/fail -processor MessagerBasics -proc:only -AfinalError MessagerBasics.java @@ -39,18 +41,16 @@ import javax.lang.model.element.*; import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") @SupportedOptions("finalError") -public class MessagerBasics extends AbstractProcessor { +public class MessagerBasics extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager m = processingEnv.getMessager(); if (roundEnv.processingOver()) { if (processingEnv.getOptions().containsKey("finalError")) - m.printMessage(ERROR, "Does not compute"); + messager.printMessage(ERROR, "Does not compute"); else { - m.printMessage(NOTE, "Post no bills"); - m.printMessage(WARNING, "Beware the ides of March!"); + messager.printMessage(NOTE, "Post no bills"); + messager.printMessage(WARNING, "Beware the ides of March!"); } } return true; diff --git a/langtools/test/tools/javac/processing/model/6194785/T6194785.java b/langtools/test/tools/javac/processing/model/6194785/T6194785.java index 8b18b48f712..11abd61a1d6 100644 --- a/langtools/test/tools/javac/processing/model/6194785/T6194785.java +++ b/langtools/test/tools/javac/processing/model/6194785/T6194785.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6194785 * @summary ParameterDeclaration.getSimpleName does not return actual name from class files * @author Peter von der Ah\u00e9 + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g T6194785.java T6194785a.java * @compile -processor T6194785 foo.T6194785a T6194785.java */ @@ -36,13 +38,10 @@ import javax.lang.model.element.*; import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6194785 extends AbstractProcessor { +public class T6194785 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - final Messager log = processingEnv.getMessager(); - final Elements elements = processingEnv.getElementUtils(); class Scan extends ElementScanner7 { @Override public Void visitExecutable(ExecutableElement e, Void ignored) { diff --git a/langtools/test/tools/javac/processing/model/6341534/T6341534.java b/langtools/test/tools/javac/processing/model/6341534/T6341534.java index b374d65eb05..2950909590e 100644 --- a/langtools/test/tools/javac/processing/model/6341534/T6341534.java +++ b/langtools/test/tools/javac/processing/model/6341534/T6341534.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ * @summary PackageElement.getEnclosedElements results in NullPointerException from parse(JavaCompiler.java:429) * @author Steve Sides * @author Peter von der Ahe + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile T6341534.java * @compile -proc:only -processor T6341534 dir/package-info.java * @compile -processor T6341534 dir/package-info.java @@ -40,20 +42,11 @@ import java.util.*; import java.util.Set; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6341534 extends AbstractProcessor { - Elements elements; - Messager messager; - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - messager = processingEnv.getMessager(); - } - +public class T6341534 extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment renv) { messager.printMessage(NOTE, - String.valueOf(elements.getPackageElement("no.such.package"))); - PackageElement dir = elements.getPackageElement("dir"); + String.valueOf(eltUtils.getPackageElement("no.such.package"))); + PackageElement dir = eltUtils.getPackageElement("dir"); messager.printMessage(NOTE, dir.getQualifiedName().toString()); for (Element e : dir.getEnclosedElements()) messager.printMessage(NOTE, e.toString()); diff --git a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java index 62c7964416f..f5bddff0a45 100644 --- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java @@ -26,7 +26,8 @@ * @bug 6449781 * @summary Test that reported names of anonymous classes are non-null. * @author Joseph D. Darcy - * @build TestAnonSourceNames + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestAnonSourceNames * @compile -processor TestAnonSourceNames TestAnonClassNames.java * @run main TestAnonClassNames */ @@ -141,8 +142,7 @@ public class TestAnonClassNames { /** * Probe at the various kinds of names of a type element. */ -@SupportedAnnotationTypes("*") -class ClassNameProber extends AbstractProcessor { +class ClassNameProber extends JavacTestingAbstractProcessor { public ClassNameProber(){super();} private boolean classesFound=false; @@ -174,8 +174,4 @@ class ClassNameProber extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java index ff16b5df389..84184b30407 100644 --- a/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java @@ -36,8 +36,7 @@ import static javax.tools.Diagnostic.Kind.*; * Using the tree API, retrieve element representations of anonymous * classes and verify their names are as specified. */ -@SupportedAnnotationTypes("*") -public class TestAnonSourceNames extends AbstractProcessor { +public class TestAnonSourceNames extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -84,9 +83,4 @@ public class TestAnonSourceNames extends AbstractProcessor { return super.visitClass(node, cu); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TestElement.java b/langtools/test/tools/javac/processing/model/element/TestElement.java index 8e38da4879e..004a5058aa2 100644 --- a/langtools/test/tools/javac/processing/model/element/TestElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6453386 * @summary Test basic properties of javax.lang.element.Element * @author Joseph D. Darcy - * @build TestElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestElement * @compile -processor TestElement -proc:only TestElement.java */ @@ -43,8 +44,7 @@ import static javax.tools.StandardLocation.*; /** * Test basic workings of javax.lang.element.Element */ -@SupportedAnnotationTypes("*") -public class TestElement extends AbstractProcessor { +public class TestElement extends JavacTestingAbstractProcessor { /** * For now, just check that constructors have a simple name of * "". @@ -66,9 +66,4 @@ public class TestElement extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - } diff --git a/langtools/test/tools/javac/processing/model/element/TestNames.java b/langtools/test/tools/javac/processing/model/element/TestNames.java index fe1683115a7..1aec65ec4bf 100644 --- a/langtools/test/tools/javac/processing/model/element/TestNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6380016 * @summary Test that the constraints guaranteed by the Filer and maintained * @author Joseph D. Darcy - * @build TestNames + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestNames * @compile -processor TestNames -proc:only TestNames.java */ @@ -45,11 +46,8 @@ import java.io.*; /** * Basic tests of semantics of javax.lang.model.element.Name */ -@SupportedAnnotationTypes("*") -public class TestNames extends AbstractProcessor { +public class TestNames extends JavacTestingAbstractProcessor { private int round = 0; - private Filer filer; - private Elements eltUtils; String stringStringName = "java.lang.String"; Name stringName = null; @@ -106,16 +104,6 @@ public class TestNames extends AbstractProcessor { return true; } - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - eltUtils = processingEnv.getElementUtils(); - } - private static class Pseudonym implements Name { private String name; diff --git a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java index 5b44c5ade98..4e0575be93b 100644 --- a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6449798 6399404 * @summary Test basic workings of PackageElement * @author Joseph D. Darcy - * @build TestPackageElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestPackageElement * @compile -processor TestPackageElement -proc:only TestPackageElement.java */ @@ -43,11 +44,7 @@ import static javax.tools.StandardLocation.*; /** * Test basic workings of PackageElement. */ -@SupportedAnnotationTypes("*") -public class TestPackageElement extends AbstractProcessor { - private Filer filer; - private Elements eltUtils; - +public class TestPackageElement extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -71,15 +68,4 @@ public class TestPackageElement extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - eltUtils = processingEnv.getElementUtils(); - } - } diff --git a/langtools/test/tools/javac/processing/model/element/TestResourceElement.java b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java index 9bb71b829a1..a6e6de829d5 100644 --- a/langtools/test/tools/javac/processing/model/element/TestResourceElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java @@ -26,7 +26,8 @@ * @bug 6967842 * @summary Element not returned from tree API for ARM resource variables. * @author A. Sundararajan - * @build TestResourceElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestResourceElement * @compile -processor TestResourceElement -proc:only TestResourceElement.java */ @@ -37,8 +38,7 @@ import java.util.*; import com.sun.source.tree.*; import com.sun.source.util.*; -@SupportedAnnotationTypes("*") -public class TestResourceElement extends AbstractProcessor implements AutoCloseable { +public class TestResourceElement extends JavacTestingAbstractProcessor implements AutoCloseable { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -88,9 +88,4 @@ public class TestResourceElement extends AbstractProcessor implements AutoClosea return trvElement; } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java index f240ba7f0ee..4b5fcd26b0e 100644 --- a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java +++ b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java @@ -26,7 +26,8 @@ * @bug 6911256 6964740 6967842 * @summary Test that the resource variable kind is appropriately set * @author Joseph D. Darcy - * @build TestResourceVariable + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestResourceVariable * @compile -processor TestResourceVariable -proc:only TestResourceVariable.java */ @@ -48,8 +49,7 @@ import static javax.tools.Diagnostic.Kind.*; * resource of an ARM block and verify their kind tags are set * appropriately. */ -@SupportedAnnotationTypes("*") -public class TestResourceVariable extends AbstractProcessor implements AutoCloseable { +public class TestResourceVariable extends JavacTestingAbstractProcessor implements AutoCloseable { int resourceVariableCount = 0; public boolean process(Set annotations, @@ -105,9 +105,4 @@ public class TestResourceVariable extends AbstractProcessor implements AutoClose return super.visitVariable(node, cu); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java b/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java index 0442c96a893..c09e12bd49b 100644 --- a/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java +++ b/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6423972 * @summary Tests TypeParameter.getBounds. * @author Scott Seligman - * @build TypeParamBounds + * @library ../../../lib + * @build JavacTestingAbstractProcessor TypeParamBounds * @compile -processor TypeParamBounds -proc:only TypeParamBounds.java */ @@ -40,18 +41,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class TypeParamBounds extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class TypeParamBounds extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -59,11 +49,6 @@ public class TypeParamBounds extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { TypeElement gen = elements.getTypeElement("TypeParamBounds.Gen"); @@ -91,7 +76,6 @@ public class TypeParamBounds extends AbstractProcessor { // Fodder for the processor - static class Gen { diff --git a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java index 30ab564a71b..861014f4cce 100644 --- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java +++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6362178 * @summary MirroredType[s]Exception shouldn't be created too eagerly * @author Scott Seligman + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile -g OverEager.java * @compile -processor OverEager -proc:only OverEager.java */ @@ -40,17 +42,7 @@ import static javax.lang.model.util.ElementFilter.*; @SupportedAnnotationTypes("IAm") @IAm(OverEager.class) -public class OverEager extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class OverEager extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -58,11 +50,6 @@ public class OverEager extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { for (TypeElement t : typesIn(round.getRootElements())) { diff --git a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java index f7b6ca6694f..e01ba019c7f 100644 --- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java +++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java @@ -25,6 +25,8 @@ * @test * @bug 6519115 * @summary Verify MirroredTypeException vs MirroredTypesException is thrown + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile Plurality.java * @compile -processor Plurality -proc:only Plurality.java * @author Joseph D. Darcy @@ -38,25 +40,13 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") @P0 @P1 @P2 @S1 -public class Plurality extends AbstractProcessor { +public class Plurality extends JavacTestingAbstractProcessor { private boolean executed = false; - Elements elements; - Types types; - - @Override - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -164,11 +154,6 @@ public class Plurality extends AbstractProcessor { toStringName); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } @Retention(RetentionPolicy.RUNTIME) diff --git a/langtools/test/tools/javac/processing/model/type/NoTypes.java b/langtools/test/tools/javac/processing/model/type/NoTypes.java index 3e26d6fd01d..d67dae187c4 100644 --- a/langtools/test/tools/javac/processing/model/type/NoTypes.java +++ b/langtools/test/tools/javac/processing/model/type/NoTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6418666 6423973 6453386 * @summary Test the NoTypes: VOID, PACKAGE, NONE * @author Scott Seligman + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g NoTypes.java * @compile -processor NoTypes -proc:only NoTypes.java */ @@ -39,18 +41,7 @@ import javax.lang.model.util.*; import static javax.lang.model.type.TypeKind.*; -@SupportedAnnotationTypes("*") -public class NoTypes extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class NoTypes extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -58,11 +49,6 @@ public class NoTypes extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { diff --git a/langtools/test/tools/javac/processing/model/util/BinaryName.java b/langtools/test/tools/javac/processing/model/util/BinaryName.java index ebf5612b1eb..02445ff2bd8 100644 --- a/langtools/test/tools/javac/processing/model/util/BinaryName.java +++ b/langtools/test/tools/javac/processing/model/util/BinaryName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6346251 * @summary Test Elements.getBinaryName * @author Scott Seligman - * @build BinaryName + * @library ../../../lib + * @build JavacTestingAbstractProcessor BinaryName * @compile -processor BinaryName -proc:only BinaryName.java */ @@ -38,17 +39,8 @@ import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.typesIn; -@SupportedAnnotationTypes("*") @HelloIm("BinaryName") -public class BinaryName extends AbstractProcessor { - - Elements elements; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - } - +public class BinaryName extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java b/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java index 92b5c088f6d..01782f327a5 100644 --- a/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java +++ b/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6346506 6408241 * @summary getTypeElement should tolerate a type that can't be found * @author Scott Seligman - * @build GetTypeElemBadArg + * @library ../../../lib + * @build JavacTestingAbstractProcessor GetTypeElemBadArg * @compile -processor GetTypeElemBadArg -proc:only GetTypeElemBadArg.java */ @@ -37,16 +38,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class GetTypeElemBadArg extends AbstractProcessor { - - Elements elements; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - } - +public class GetTypeElemBadArg extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; @@ -63,12 +55,6 @@ public class GetTypeElemBadArg extends AbstractProcessor { return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private static void tellAbout(TypeElement t) { System.out.println(t); System.out.println(t.getClass()); diff --git a/langtools/test/tools/javac/processing/model/util/NoSupers.java b/langtools/test/tools/javac/processing/model/util/NoSupers.java index 64671cc5fae..9967b405580 100644 --- a/langtools/test/tools/javac/processing/model/util/NoSupers.java +++ b/langtools/test/tools/javac/processing/model/util/NoSupers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6346453 * @summary directSupertypes should return empty list if arg has no supertypes * @author Scott Seligman - * @build NoSupers + * @library ../../../lib + * @build JavacTestingAbstractProcessor NoSupers * @compile -processor NoSupers -proc:only NoSupers.java */ @@ -36,16 +37,7 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class NoSupers extends AbstractProcessor { - - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - types = penv.getTypeUtils(); - } - +public class NoSupers extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java b/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java index e6c7916dbeb..887c6776fb7 100644 --- a/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java +++ b/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6453386 * @summary Verify that example code in Elements.overrides works as spec'ed. * @author Scott Seligman + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g OverridesSpecEx.java * @compile -processor OverridesSpecEx -proc:only OverridesSpecEx.java */ @@ -39,19 +41,7 @@ import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.*; - -@SupportedAnnotationTypes("*") -public class OverridesSpecEx extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class OverridesSpecEx extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -59,11 +49,6 @@ public class OverridesSpecEx extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { TypeElement string = elements.getTypeElement("java.lang.String"); @@ -113,9 +98,7 @@ public class OverridesSpecEx extends AbstractProcessor { throw new AssertionError("Bogus result"); } - // Fodder for the processor - class A { public void m() {} } diff --git a/langtools/test/tools/javac/processing/model/util/TypesBadArg.java b/langtools/test/tools/javac/processing/model/util/TypesBadArg.java index 8f13c8f7d68..6eadb5759a7 100644 --- a/langtools/test/tools/javac/processing/model/util/TypesBadArg.java +++ b/langtools/test/tools/javac/processing/model/util/TypesBadArg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6345812 * @summary Validate argument kinds in Types utilities * @author Scott Seligman - * @build TypesBadArg + * @library ../../../lib + * @build JavacTestingAbstractProcessor TypesBadArg * @compile -processor TypesBadArg -proc:only TypesBadArg.java */ @@ -36,15 +37,9 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class TypesBadArg extends AbstractProcessor { - +public class TypesBadArg extends JavacTestingAbstractProcessor { boolean success = true; - public void init(ProcessingEnvironment penv) { - super.init(penv); - } - public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java b/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java index a7ff90ba060..ce9b2cdf92c 100644 --- a/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java +++ b/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6392818 * @summary Tests Elements.isDeprecated(Element) * @author Joseph D. Darcy + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile TestDeprecation.java * @compile -processor TestDeprecation -proc:only Dep1.java * @compile Dep1.java @@ -47,8 +49,7 @@ import java.io.Writer; * getElementsAnnotatedWith is consistent with the expected results * stored in an AnnotatedElementInfo annotation. */ -@SupportedAnnotationTypes("*") -public class TestDeprecation extends AbstractProcessor { +public class TestDeprecation extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -98,9 +99,4 @@ public class TestDeprecation extends AbstractProcessor { return failure; } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff --git a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java index b74a5dc0af8..db44b564747 100644 --- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6346973 * @summary directSupertypes(t) should not return t * @author Scott Seligman - * @build DirectSupersOfErr + * @library ../../../../lib + * @build JavacTestingAbstractProcessor DirectSupersOfErr * @compile -processor DirectSupersOfErr -proc:only C1.java */ @@ -37,16 +38,7 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.*; -@SupportedAnnotationTypes("*") -public class DirectSupersOfErr extends AbstractProcessor { - - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - types = penv.getTypeUtils(); - } - +public class DirectSupersOfErr extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff --git a/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java b/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java index 17543c6ee9a..355b7d93bc8 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java +++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6471577 6517779 * @summary Test Elements.getConstantExpression * @author Joseph D. Darcy - * @build TestGetConstantExpression + * @library ../../../../lib + * @build JavacTestingAbstractProcessor TestGetConstantExpression * @compile -processor TestGetConstantExpression Foo.java */ @@ -44,10 +45,7 @@ import java.io.*; /** * Test basic workings of Elements.getConstantExpression. */ -@SupportedAnnotationTypes("*") -public class TestGetConstantExpression extends AbstractProcessor { - private Elements eltUtils; - private Filer filer; +public class TestGetConstantExpression extends JavacTestingAbstractProcessor { private int round = 1; /** @@ -130,14 +128,4 @@ public class TestGetConstantExpression extends AbstractProcessor { return 0; } } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - filer = processingEnv.getFiler(); - } } diff --git a/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java b/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java index 08e4702104d..6fbc24f0cf8 100644 --- a/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java +++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 6453386 * @summary Test Elements.getPackageOf * @author Joseph D. Darcy - * @build TestGetPackageOf + * @library ../../../../lib + * @build JavacTestingAbstractProcessor TestGetPackageOf * @compile -processor TestGetPackageOf -proc:only TestGetPackageOf.java */ @@ -43,10 +44,7 @@ import static javax.tools.StandardLocation.*; /** * Test basic workings of Elements.getPackageOf */ -@SupportedAnnotationTypes("*") -public class TestGetPackageOf extends AbstractProcessor { - private Elements eltUtils; - +public class TestGetPackageOf extends JavacTestingAbstractProcessor { /** * Check expected behavior on classes and packages. */ @@ -69,13 +67,4 @@ public class TestGetPackageOf extends AbstractProcessor { } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - } } diff --git a/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java b/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java index 2b906b32e75..cbffcda752d 100644 --- a/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java +++ b/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ * @bug 6406164 * @summary Test that ElementFilter iterable methods behave properly. * @author Joseph D. Darcy + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile TestIterables.java * @compile -processor TestIterables -proc:only Foo1.java * @compile Foo1.java @@ -51,9 +53,8 @@ import static javax.lang.model.util.ElementFilter.*; * results. */ @SupportedAnnotationTypes("ExpectedElementCounts") -@ExpectedElementCounts(methods=3) -public class TestIterables extends AbstractProcessor { - +@ExpectedElementCounts(methods=2) +public class TestIterables extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -118,10 +119,4 @@ public class TestIterables extends AbstractProcessor { return count1; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - } diff --git a/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java b/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java index a89d947d7b2..bba89985c57 100644 --- a/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java +++ b/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,8 @@ import static javax.tools.Diagnostic.Kind.*; /** * This processor returns the supported source level as indicated by - * the "SourceLevel" option. + * the "SourceLevel" option; therefore, don't use + * JavacTestingAbstractProcessor which returns the latest source level. */ @SupportedAnnotationTypes("*") @SupportedOptions("SourceVersion") diff --git a/langtools/test/tools/javac/processing/werror/WError1.java b/langtools/test/tools/javac/processing/werror/WError1.java index a247b72723e..08cbe7383d7 100644 --- a/langtools/test/tools/javac/processing/werror/WError1.java +++ b/langtools/test/tools/javac/processing/werror/WError1.java @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WError1.java * @compile -proc:only -processor WError1 WError1.java * @compile/fail/ref=WError1.out -XDrawDiagnostics -Werror -proc:only -processor WError1 WError1.java @@ -36,22 +38,15 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WError1 extends AbstractProcessor { +public class WError1 extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); if (++round == 1) { messager.printMessage(Diagnostic.Kind.WARNING, "round 1"); } return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - int round = 0; } diff --git a/langtools/test/tools/javac/processing/werror/WErrorGen.java b/langtools/test/tools/javac/processing/werror/WErrorGen.java index 3c622f009f7..383ee791af9 100644 --- a/langtools/test/tools/javac/processing/werror/WErrorGen.java +++ b/langtools/test/tools/javac/processing/werror/WErrorGen.java @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WErrorGen.java * @compile -proc:only -processor WErrorGen WErrorGen.java * @compile/fail/ref=WErrorGen.out -XDrawDiagnostics -Werror -Xlint:rawtypes -processor WErrorGen WErrorGen.java @@ -36,12 +38,10 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WErrorGen extends AbstractProcessor { +public class WErrorGen extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Filer filer = processingEnv.getFiler(); if (++round == 1) { try { JavaFileObject fo = filer.createSourceFile("Gen"); @@ -54,10 +54,5 @@ public class WErrorGen extends AbstractProcessor { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - int round = 0; } diff --git a/langtools/test/tools/javac/processing/werror/WErrorLast.java b/langtools/test/tools/javac/processing/werror/WErrorLast.java index e2ba67f5c9e..33578c84846 100644 --- a/langtools/test/tools/javac/processing/werror/WErrorLast.java +++ b/langtools/test/tools/javac/processing/werror/WErrorLast.java @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WErrorLast.java * @compile -proc:only -processor WErrorLast WErrorLast.java * @compile/fail/ref=WErrorLast.out -XDrawDiagnostics -Werror -proc:only -processor WErrorLast WErrorLast.java @@ -36,20 +38,13 @@ import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WErrorLast extends AbstractProcessor { +public class WErrorLast extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); if (roundEnv.processingOver()) { messager.printMessage(Diagnostic.Kind.WARNING, "last round"); } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } From 35092b1bf326026dbc365dfa7784f2207a48225f Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Thu, 30 Sep 2010 14:50:36 +0400 Subject: [PATCH 55/88] 6694729: obsolete link in ActionEvent javadoc Reviewed-by: art --- jdk/src/share/classes/java/awt/event/ActionEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/event/ActionEvent.java b/jdk/src/share/classes/java/awt/event/ActionEvent.java index ec29e6d09f5..3d5280aa658 100644 --- a/jdk/src/share/classes/java/awt/event/ActionEvent.java +++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java @@ -51,7 +51,7 @@ import java.awt.Event; * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}. * * @see ActionListener - * @see Tutorial: Java 1.1 Event Model + * @see Tutorial: How to Write an Action Listener * * @author Carl Quinn * @since 1.1 From ce43c743ff46a03bbe88a4817e1caeec27c53496 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 30 Sep 2010 14:48:25 +0100 Subject: [PATCH 56/88] 6988037: fileClose prints debug message is close fails Reviewed-by: kevinw, forax --- jdk/src/solaris/native/java/io/io_util_md.c | 4 +--- jdk/src/windows/native/java/io/io_util_md.c | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/jdk/src/solaris/native/java/io/io_util_md.c b/jdk/src/solaris/native/java/io/io_util_md.c index 6379acfe16a..eb27ff26794 100644 --- a/jdk/src/solaris/native/java/io/io_util_md.c +++ b/jdk/src/solaris/native/java/io/io_util_md.c @@ -83,8 +83,6 @@ fileClose(JNIEnv *env, jobject this, jfieldID fid) close(devnull); } } else if (JVM_Close(fd) == -1) { - SET_FD(this, fd, fid); // restore fd - printf("JVM_Close returned -1\n"); - JNU_ThrowIOExceptionWithLastError(env, "close failed"); + JNU_ThrowIOExceptionWithLastError(env, "close failed"); } } diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index 93e154cd639..f5b9723a743 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -531,7 +531,6 @@ handleClose(JNIEnv *env, jobject this, jfieldID fid) SET_FD(this, -1, fid); if (CloseHandle(h) == 0) { /* Returns zero on failure */ - SET_FD(this, fd, fid); // restore fd JNU_ThrowIOExceptionWithLastError(env, "close failed"); } return 0; From 55c5ae30110b2b16bf2e0381d8d2ed15b3ddab9d Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 30 Sep 2010 20:21:55 +0400 Subject: [PATCH 57/88] 6982753: javax/swing/JTextArea/6940863/bug6940863.java should be modified Reviewed-by: alexp --- jdk/test/javax/swing/JTextArea/6940863/bug6940863.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java b/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java index ffcd2d44aa5..b868d41adfc 100644 --- a/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java +++ b/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java @@ -56,6 +56,7 @@ public class bug6940863 { public static void main(String[] args) throws Exception { if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { System.out.println("The test is suitable only for Windows OS. Skipped"); + return; } UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); From 013d4693223fdfacd25d55f7020178c0b3d1619f Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Thu, 30 Sep 2010 21:06:53 +0400 Subject: [PATCH 58/88] 6860270: JVM crash is occuring when verifying whether Browse action is supported on WinVista 64 bit Reviewed-by: anthony, uta --- jdk/src/windows/native/sun/windows/awt_Desktop.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp index 4121c8af9b5..67506f3bc1e 100644 --- a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp @@ -59,15 +59,17 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - GetLastError(), + (int)retval, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&buffer, 0, NULL ); - jstring errmsg = JNU_NewStringPlatform(env, buffer, len); - LocalFree(buffer); - return errmsg; + if (buffer) { + jstring errmsg = JNU_NewStringPlatform(env, buffer); + LocalFree(buffer); + return errmsg; + } } return NULL; From b281273d712d3428f584cd7c20fcfcae91561a83 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 30 Sep 2010 10:47:12 -0700 Subject: [PATCH 59/88] 6988436: Cleanup javac option handling Reviewed-by: darcy --- .../com/sun/tools/javac/code/Source.java | 11 ++-- .../com/sun/tools/javac/comp/Attr.java | 8 +-- .../com/sun/tools/javac/comp/Check.java | 11 ++-- .../com/sun/tools/javac/comp/Lower.java | 2 +- .../com/sun/tools/javac/comp/MemberEnter.java | 2 +- .../com/sun/tools/javac/comp/Resolve.java | 6 +- .../tools/javac/file/JavacFileManager.java | 10 +-- .../com/sun/tools/javac/jvm/ClassReader.java | 14 +++-- .../com/sun/tools/javac/jvm/ClassWriter.java | 19 +++--- .../classes/com/sun/tools/javac/jvm/Gen.java | 19 +++--- .../com/sun/tools/javac/jvm/Target.java | 4 +- .../sun/tools/javac/main/JavaCompiler.java | 63 +++++++++---------- .../com/sun/tools/javac/main/Main.java | 36 ++++++----- .../tools/javac/processing/JavacFiler.java | 24 ++++--- .../JavacProcessingEnvironment.java | 27 ++++---- .../classes/com/sun/tools/javac/util/Log.java | 21 ++++--- .../com/sun/tools/javac/util/Names.java | 2 +- .../com/sun/tools/javac/util/Options.java | 59 +++++++++++++++-- 18 files changed, 203 insertions(+), 135 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java index 58fa9a7694a..3a21ce72135 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java @@ -25,11 +25,14 @@ package com.sun.tools.javac.code; -import com.sun.tools.javac.util.*; -import com.sun.tools.javac.jvm.Target; +import java.util.*; import javax.lang.model.SourceVersion; import static javax.lang.model.SourceVersion.*; -import java.util.*; + +import com.sun.tools.javac.util.*; +import com.sun.tools.javac.jvm.Target; + +import static com.sun.tools.javac.main.OptionName.*; /** The source language version accepted. * @@ -71,7 +74,7 @@ public enum Source { Source instance = context.get(sourceKey); if (instance == null) { Options options = Options.instance(context); - String sourceString = options.get("-source"); + String sourceString = options.get(SOURCE); if (sourceString != null) instance = lookup(sourceString); if (instance == null) instance = DEFAULT; context.put(sourceKey, instance); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index ab6c322e7db..7e80d2693cb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -119,10 +119,10 @@ public class Attr extends JCTree.Visitor { allowAnonOuterThis = source.allowAnonOuterThis(); allowStringsInSwitch = source.allowStringsInSwitch(); sourceName = source.name; - relax = (options.get("-retrofit") != null || - options.get("-relax") != null); - useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; - enableSunApiLintControl = options.get("enableSunApiLintControl") != null; + relax = (options.isSet("-retrofit") || + options.isSet("-relax")); + useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); + enableSunApiLintControl = options.isSet("enableSunApiLintControl"); } /** Switch: relax some constraints for retrofit mode. diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index de78acb5097..07d95cc5c1e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -25,7 +25,6 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.AssignmentTree; import java.util.*; import java.util.Set; @@ -46,6 +45,8 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.main.OptionName.*; + /** Type checking helper class for the attribution phase. * *

    This is NOT part of any supported API. @@ -99,10 +100,10 @@ public class Check { allowGenerics = source.allowGenerics(); allowAnnotations = source.allowAnnotations(); allowCovariantReturns = source.allowCovariantReturns(); - complexInference = options.get("-complexinference") != null; - skipAnnotations = options.get("skipAnnotations") != null; - warnOnSyntheticConflicts = options.get("warnOnSyntheticConflicts") != null; - suppressAbortOnBadClassFile = options.get("suppressAbortOnBadClassFile") != null; + complexInference = options.isSet(COMPLEXINFERENCE); + skipAnnotations = options.isSet("skipAnnotations"); + warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); + suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); Target target = Target.instance(context); syntheticNameChar = target.syntheticNameChar(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 67f42b821a4..9498781064e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -109,7 +109,7 @@ public class Lower extends TreeTranslator { types = Types.instance(context); Options options = Options.instance(context); - debugLower = options.get("debuglower") != null; + debugLower = options.isSet("debuglower"); pkginfoOpt = PkgInfo.get(options); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 09cd303b80e..73fe36cbf7d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -102,7 +102,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { diags = JCDiagnostic.Factory.instance(context); target = Target.instance(context); Options options = Options.instance(context); - skipAnnotations = options.get("skipAnnotations") != null; + skipAnnotations = options.isSet("skipAnnotations"); } /** A queue for classes whose members still need to be entered into the diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 10141b1e58f..85d8161dac6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -110,14 +110,14 @@ public class Resolve { boxingEnabled = source.allowBoxing(); varargsEnabled = source.allowVarargs(); Options options = Options.instance(context); - debugResolve = options.get("debugresolve") != null; - allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null; + debugResolve = options.isSet("debugresolve"); + allowTransitionalJSR292 = options.isSet("allowTransitionalJSR292"); Target target = Target.instance(context); allowMethodHandles = allowTransitionalJSR292 || target.hasMethodHandles(); allowInvokeDynamic = (allowTransitionalJSR292 || target.hasInvokedynamic()) && - options.get("invokedynamic") != null; + options.isSet("invokedynamic"); polymorphicSignatureScope = new Scope(syms.noSymbol); inapplicableMethodException = new InapplicableMethodException(diags); diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index afa40d10d37..5fec67baecc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -150,8 +150,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; - mmappedIO = options.get("mmappedIO") != null; - ignoreSymbolFile = options.get("ignore.symbol.file") != null; + mmappedIO = options.isSet("mmappedIO"); + ignoreSymbolFile = options.isSet("ignore.symbol.file"); } public JavaFileObject getFileForInput(String name) { @@ -435,7 +435,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil zdir = new ZipFile(zipFileName); } else { - usePreindexedCache = options.get("usezipindex") != null; + usePreindexedCache = options.isSet("usezipindex"); preindexCacheLocation = options.get("java.io.tmpdir"); String optCacheLoc = options.get("cachezipindexdir"); @@ -469,7 +469,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil null, usePreindexedCache, preindexCacheLocation, - options.get("writezipindexfiles") != null)); + options.isSet("writezipindexfiles"))); } } else { @@ -482,7 +482,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil symbolFilePrefix, usePreindexedCache, preindexCacheLocation, - options.get("writezipindexfiles") != null)); + options.isSet("writezipindexfiles"))); } } } catch (FileNotFoundException ex) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 4e76d78e2a5..912d0dbf293 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -56,6 +56,8 @@ import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ClassFile.*; import static com.sun.tools.javac.jvm.ClassFile.Version.*; +import static com.sun.tools.javac.main.OptionName.*; + /** This class provides operations to read a classfile into an internal * representation. The internal representation is anchored in a * ClassSymbol which contains in its scope symbol representations @@ -259,23 +261,23 @@ public class ClassReader implements Completer { Options options = Options.instance(context); annotate = Annotate.instance(context); - verbose = options.get("-verbose") != null; - checkClassFile = options.get("-checkclassfile") != null; + verbose = options.isSet(VERBOSE); + checkClassFile = options.isSet("-checkclassfile"); Source source = Source.instance(context); allowGenerics = source.allowGenerics(); allowVarargs = source.allowVarargs(); allowAnnotations = source.allowAnnotations(); - saveParameterNames = options.get("save-parameter-names") != null; - cacheCompletionFailure = options.get("dev") == null; + saveParameterNames = options.isSet("save-parameter-names"); + cacheCompletionFailure = options.isUnset("dev"); preferSource = "source".equals(options.get("-Xprefer")); completionFailureName = - (options.get("failcomplete") != null) + options.isSet("failcomplete") ? names.fromString(options.get("failcomplete")) : null; typevars = new Scope(syms.noSymbol); - debugJSR308 = options.get("TA:reader") != null; + debugJSR308 = options.isSet("TA:reader"); initAttributeReaders(); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index a413b6fe1c7..08797b63e69 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -45,8 +45,10 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.UninitializedType.*; +import static com.sun.tools.javac.main.OptionName.*; import static javax.tools.StandardLocation.CLASS_OUTPUT; + /** This class provides operations to map an internal symbol table graph * rooted in a ClassSymbol into a classfile. * @@ -178,15 +180,16 @@ public class ClassWriter extends ClassFile { types = Types.instance(context); fileManager = context.get(JavaFileManager.class); - debugJSR308 = options.get("TA:writer") != null; - verbose = options.get("-verbose") != null; - scramble = options.get("-scramble") != null; - scrambleAll = options.get("-scrambleAll") != null; - retrofit = options.get("-retrofit") != null; - genCrt = options.get("-Xjcov") != null; - debugstackmap = options.get("debugstackmap") != null; + debugJSR308 = options.isSet("TA:writer"); + verbose = options.isSet(VERBOSE); + scramble = options.isSet("-scramble"); + scrambleAll = options.isSet("-scrambleAll"); + retrofit = options.isSet("-retrofit"); + genCrt = options.isSet(XJCOV); + debugstackmap = options.isSet("debugstackmap"); - emitSourceFile = options.get("-g:")==null || options.get("-g:source")!=null; + emitSourceFile = options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "source"); String dumpModFlags = options.get("dumpmodifiers"); dumpClassModifiers = diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index 188793a453a..572380a49e1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -46,6 +46,7 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.CRTFlags.*; +import static com.sun.tools.javac.main.OptionName.*; /** This pass maps flat Java (i.e. without inner classes) to bytecodes. * @@ -113,19 +114,19 @@ public class Gen extends JCTree.Visitor { Options options = Options.instance(context); lineDebugInfo = - options.get("-g:") == null || - options.get("-g:lines") != null; + options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "lines"); varDebugInfo = - options.get("-g:") == null - ? options.get("-g") != null - : options.get("-g:vars") != null; - genCrt = options.get("-Xjcov") != null; - debugCode = options.get("debugcode") != null; - allowInvokedynamic = target.hasInvokedynamic() || options.get("invokedynamic") != null; + options.isUnset(G_CUSTOM) + ? options.isSet(G) + : options.isSet(G_CUSTOM, "vars"); + genCrt = options.isSet(XJCOV); + debugCode = options.isSet("debugcode"); + allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic"); generateIproxies = target.requiresIproxy() || - options.get("miranda") != null; + options.isSet("miranda"); if (target.generateStackMapTable()) { // ignore cldc because we cannot have both stackmap formats diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java index 368c77d801c..9d09967b3da 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java @@ -31,6 +31,8 @@ import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.util.*; +import static com.sun.tools.javac.main.OptionName.*; + /** The classfile version target. * *

    This is NOT part of any supported API. @@ -73,7 +75,7 @@ public enum Target { Target instance = context.get(targetKey); if (instance == null) { Options options = Options.instance(context); - String targetString = options.get("-target"); + String targetString = options.get(TARGET); if (targetString != null) instance = lookup(targetString); if (instance == null) instance = DEFAULT; context.put(targetKey, instance); diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 04924fb9818..7e1996a45d9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -26,45 +26,44 @@ package com.sun.tools.javac.main; import java.io.*; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.MissingResourceException; +import java.util.Queue; import java.util.ResourceBundle; import java.util.Set; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.processing.Processor; +import javax.lang.model.SourceVersion; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.DiagnosticListener; -import com.sun.tools.javac.file.JavacFileManager; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; +import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.*; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.*; +import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.parser.*; import com.sun.tools.javac.comp.*; import com.sun.tools.javac.jvm.*; - -import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.tree.JCTree.*; - import com.sun.tools.javac.processing.*; -import javax.annotation.processing.Processor; import static javax.tools.StandardLocation.CLASS_OUTPUT; +import static com.sun.tools.javac.main.OptionName.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; import static com.sun.tools.javac.util.ListBuffer.lb; -import java.util.HashMap; -import java.util.Queue; -import javax.lang.model.SourceVersion; /** This class could be the main entry point for GJC when GJC is used as a * component in a larger software system. It provides operations to @@ -356,22 +355,22 @@ public class JavaCompiler implements ClassReader.SourceCompleter { Options options = Options.instance(context); - verbose = options.get("-verbose") != null; - sourceOutput = options.get("-printsource") != null; // used to be -s - stubOutput = options.get("-stubs") != null; - relax = options.get("-relax") != null; - printFlat = options.get("-printflat") != null; - attrParseOnly = options.get("-attrparseonly") != null; - encoding = options.get("-encoding"); - lineDebugInfo = options.get("-g:") == null || - options.get("-g:lines") != null; - genEndPos = options.get("-Xjcov") != null || + verbose = options.isSet(VERBOSE); + sourceOutput = options.isSet(PRINTSOURCE); // used to be -s + stubOutput = options.isSet("-stubs"); + relax = options.isSet("-relax"); + printFlat = options.isSet("-printflat"); + attrParseOnly = options.isSet("-attrparseonly"); + encoding = options.get(ENCODING); + lineDebugInfo = options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "lines"); + genEndPos = options.isSet(XJCOV) || context.get(DiagnosticListener.class) != null; - devVerbose = options.get("dev") != null; - processPcks = options.get("process.packages") != null; - werror = options.get("-Werror") != null; + devVerbose = options.isSet("dev"); + processPcks = options.isSet("process.packages"); + werror = options.isSet(WERROR); - verboseCompilePolicy = options.get("verboseCompilePolicy") != null; + verboseCompilePolicy = options.isSet("verboseCompilePolicy"); if (attrParseOnly) compilePolicy = CompilePolicy.ATTR_ONLY; @@ -381,15 +380,15 @@ public class JavaCompiler implements ClassReader.SourceCompleter { implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit")); completionFailureName = - (options.get("failcomplete") != null) + options.isSet("failcomplete") ? names.fromString(options.get("failcomplete")) : null; shouldStopPolicy = - (options.get("shouldStopPolicy") != null) + options.isSet("shouldStopPolicy") ? CompileState.valueOf(options.get("shouldStopPolicy")) : null; - if (options.get("oldDiags") == null) + if (options.isUnset("oldDiags")) log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context)); } @@ -954,7 +953,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { // Process annotations if processing is not disabled and there // is at least one Processor available. Options options = Options.instance(context); - if (options.get("-proc:none") != null) { + if (options.isSet(PROC, "none")) { processAnnotations = false; } else if (procEnvImpl == null) { procEnvImpl = new JavacProcessingEnvironment(context, processors); @@ -1013,7 +1012,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { // annotation processing is to occur with compilation, // emit a warning. Options options = Options.instance(context); - if (options.get("-proc:only") != null) { + if (options.isSet(PROC, "only")) { log.warning("proc.proc-only.requested.no.procs"); todo.clear(); } @@ -1101,10 +1100,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter { Options options = Options.instance(context); return explicitAnnotationProcessingRequested || - options.get("-processor") != null || - options.get("-processorpath") != null || - options.get("-proc:only") != null || - options.get("-Xprint") != null; + options.isSet(PROCESSOR) || + options.isSet(PROCESSORPATH) || + options.isSet(PROC, "only") || + options.isSet(XPRINT); } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java index 2c89774790d..e5e53dc1ad3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java @@ -32,6 +32,9 @@ import java.net.URL; import java.security.DigestInputStream; import java.security.MessageDigest; import java.util.MissingResourceException; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.annotation.processing.Processor; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.file.CacheFSInfo; @@ -41,9 +44,8 @@ import com.sun.tools.javac.main.JavacOption.Option; import com.sun.tools.javac.main.RecognizedOptions.OptionHelper; import com.sun.tools.javac.util.*; import com.sun.tools.javac.processing.AnnotationProcessingError; -import javax.tools.JavaFileManager; -import javax.tools.JavaFileObject; -import javax.annotation.processing.Processor; + +import static com.sun.tools.javac.main.OptionName.*; /** This class provides a commandline interface to the GJC compiler. * @@ -239,16 +241,16 @@ public class Main { } } - if (!checkDirectory("-d")) + if (!checkDirectory(D)) return null; - if (!checkDirectory("-s")) + if (!checkDirectory(S)) return null; - String sourceString = options.get("-source"); + String sourceString = options.get(SOURCE); Source source = (sourceString != null) ? Source.lookup(sourceString) : Source.DEFAULT; - String targetString = options.get("-target"); + String targetString = options.get(TARGET); Target target = (targetString != null) ? Target.lookup(targetString) : Target.DEFAULT; @@ -285,7 +287,7 @@ public class Main { // phase this out with JSR 292 PFD if ("no".equals(options.get("allowTransitionalJSR292"))) { options.put("allowTransitionalJSR292", null); - } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) { + } else if (target.hasInvokedynamic() && options.isUnset("allowTransitionalJSR292")) { options.put("allowTransitionalJSR292", "allowTransitionalJSR292"); } @@ -300,7 +302,7 @@ public class Main { return filenames.toList(); } // where - private boolean checkDirectory(String optName) { + private boolean checkDirectory(OptionName optName) { String value = options.get(optName); if (value == null) return true; @@ -367,10 +369,10 @@ public class Main { return EXIT_CMDERR; } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) { // it is allowed to compile nothing if just asking for help or version info - if (options.get("-help") != null - || options.get("-X") != null - || options.get("-version") != null - || options.get("-fullversion") != null) + if (options.isSet(HELP) + || options.isSet(X) + || options.isSet(VERSION) + || options.isSet(FULLVERSION)) return EXIT_OK; error("err.no.source.files"); return EXIT_CMDERR; @@ -382,7 +384,7 @@ public class Main { return EXIT_SYSERR; } - boolean forceStdOut = options.get("stdout") != null; + boolean forceStdOut = options.isSet("stdout"); if (forceStdOut) { out.flush(); out = new PrintWriter(System.out, true); @@ -391,7 +393,7 @@ public class Main { context.put(Log.outKey, out); // allow System property in following line as a Mustang legacy - boolean batchMode = (options.get("nonBatchMode") == null + boolean batchMode = (options.isUnset("nonBatchMode") && System.getProperty("nonBatchMode") == null); if (batchMode) CacheFSInfo.preRegister(context); @@ -455,7 +457,7 @@ public class Main { // for buggy compiler error recovery by swallowing thrown // exceptions. if (comp == null || comp.errorCount() == 0 || - options == null || options.get("dev") != null) + options == null || options.isSet("dev")) bugMessage(ex); return EXIT_ABNORMAL; } finally { @@ -478,7 +480,7 @@ public class Main { */ void feMessage(Throwable ex) { Log.printLines(out, ex.getMessage()); - if (ex.getCause() != null && options.get("dev") != null) { + if (ex.getCause() != null && options.isSet("dev")) { ex.getCause().printStackTrace(out); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java index 6b9ec8e1e54..d02a9147d1d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java @@ -25,14 +25,6 @@ package com.sun.tools.javac.processing; -import com.sun.tools.javac.util.*; -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.NestingKind; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.Element; -import java.util.*; - import java.io.Closeable; import java.io.FileNotFoundException; import java.io.InputStream; @@ -43,14 +35,26 @@ import java.io.Writer; import java.io.FilterWriter; import java.io.PrintWriter; import java.io.IOException; +import java.util.*; -import javax.tools.*; import static java.util.Collections.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.NestingKind; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Element; +import javax.tools.*; import javax.tools.JavaFileManager.Location; + import static javax.tools.StandardLocation.SOURCE_OUTPUT; import static javax.tools.StandardLocation.CLASS_OUTPUT; +import com.sun.tools.javac.code.Lint; +import com.sun.tools.javac.util.*; + +import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; + /** * The FilerImplementation class must maintain a number of * constraints. First, multiple attempts to open the same path within @@ -366,7 +370,7 @@ public class JavacFiler implements Filer, Closeable { aggregateGeneratedSourceNames = new LinkedHashSet(); aggregateGeneratedClassNames = new LinkedHashSet(); - lint = (Options.instance(context)).lint("processing"); + lint = (Lint.instance(context)).isEnabled(PROCESSING); } public JavaFileObject createSourceFile(CharSequence name, diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index b393fe52cb6..49ca742a580 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -79,6 +79,8 @@ import com.sun.tools.javac.util.Options; import static javax.tools.StandardLocation.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; +import static com.sun.tools.javac.main.OptionName.*; +import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; /** * Objects of this class hold and manage the state needed to support @@ -160,15 +162,14 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea source = Source.instance(context); diags = JCDiagnostic.Factory.instance(context); options = Options.instance(context); - printProcessorInfo = options.get("-XprintProcessorInfo") != null; - printRounds = options.get("-XprintRounds") != null; - verbose = options.get("-verbose") != null; - lint = options.lint("processing"); - procOnly = options.get("-proc:only") != null || - options.get("-Xprint") != null; - fatalErrors = options.get("fatalEnterError") != null; - showResolveErrors = options.get("showResolveErrors") != null; - werror = options.get("-Werror") != null; + printProcessorInfo = options.isSet(XPRINTPROCESSORINFO); + printRounds = options.isSet(XPRINTROUNDS); + verbose = options.isSet(VERBOSE); + lint = Lint.instance(context).isEnabled(PROCESSING); + procOnly = options.isSet(PROC, "only") || options.isSet(XPRINT); + fatalErrors = options.isSet("fatalEnterError"); + showResolveErrors = options.isSet("showResolveErrors"); + werror = options.isSet(WERROR); platformAnnotations = initPlatformAnnotations(); foundTypeProcessors = false; @@ -200,7 +201,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea Log log = Log.instance(context); Iterator processorIterator; - if (options.get("-Xprint") != null) { + if (options.isSet(XPRINT)) { try { Processor processor = PrintingProcessor.class.newInstance(); processorIterator = List.of(processor).iterator(); @@ -213,7 +214,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } else if (processors != null) { processorIterator = processors.iterator(); } else { - String processorNames = options.get("-processor"); + String processorNames = options.get(PROCESSOR); JavaFileManager fileManager = context.get(JavaFileManager.class); try { // If processorpath is not explicitly set, use the classpath. @@ -264,7 +265,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH) : standardFileManager.getLocation(CLASS_PATH); - if (needClassLoader(options.get("-processor"), workingPath) ) + if (needClassLoader(options.get(PROCESSOR), workingPath) ) handleException(key, e); } else { @@ -745,7 +746,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea psi.runContributingProcs(renv); // Debugging - if (options.get("displayFilerState") != null) + if (options.isSet("displayFilerState")) filer.displayState(); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index 0ffdc1a6ac0..315d3e75ff0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -35,11 +35,14 @@ import java.util.Set; import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.api.DiagnosticFormatter; +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; +import static com.sun.tools.javac.main.OptionName.*; + /** A class for error logs. Reports errors and warnings, and * keeps track of error numbers and positions. * @@ -129,14 +132,14 @@ public class Log extends AbstractLog { this.noticeWriter = noticeWriter; Options options = Options.instance(context); - this.dumpOnError = options.get("-doe") != null; - this.promptOnError = options.get("-prompt") != null; - this.emitWarnings = options.get("-Xlint:none") == null; - this.suppressNotes = options.get("suppressNotes") != null; - this.MaxErrors = getIntOption(options, "-Xmaxerrs", getDefaultMaxErrors()); - this.MaxWarnings = getIntOption(options, "-Xmaxwarns", getDefaultMaxWarnings()); + this.dumpOnError = options.isSet(DOE); + this.promptOnError = options.isSet(PROMPT); + this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none"); + this.suppressNotes = options.isSet("suppressNotes"); + this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors()); + this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings()); - boolean rawDiagnostics = options.get("rawDiagnostics") != null; + boolean rawDiagnostics = options.isSet("rawDiagnostics"); messages = JavacMessages.instance(context); this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) : new BasicDiagnosticFormatter(options, messages); @@ -150,7 +153,7 @@ public class Log extends AbstractLog { expectDiagKeys = new HashSet(Arrays.asList(ek.split(", *"))); } // where - private int getIntOption(Options options, String optionName, int defaultValue) { + private int getIntOption(Options options, OptionName optionName, int defaultValue) { String s = options.get(optionName); try { if (s != null) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java index a0c7218878d..9b939ea7341 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java @@ -271,7 +271,7 @@ public class Names { } protected Name.Table createTable(Options options) { - boolean useUnsharedTable = options.get("useUnsharedTable") != null; + boolean useUnsharedTable = options.isSet("useUnsharedTable"); if (useUnsharedTable) return new UnsharedNameTable(this); else diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java index 23eb56fd37c..100c0f03f99 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java @@ -25,8 +25,9 @@ package com.sun.tools.javac.util; -import com.sun.tools.javac.main.OptionName; import java.util.*; +import com.sun.tools.javac.main.OptionName; +import static com.sun.tools.javac.main.OptionName.*; /** A table of all command-line options. * If an option has an argument, the option name is mapped to the argument. @@ -60,14 +61,62 @@ public class Options { context.put(optionsKey, this); } + /** + * Get the value for an undocumented option. + */ public String get(String name) { return values.get(name); } + /** + * Get the value for an option. + */ public String get(OptionName name) { return values.get(name.optionName); } + /** + * Check if the value for an undocumented option has been set. + */ + public boolean isSet(String name) { + return (values.get(name) != null); + } + + /** + * Check if the value for an option has been set. + */ + public boolean isSet(OptionName name) { + return (values.get(name.optionName) != null); + } + + /** + * Check if the value for a choice option has been set to a specific value. + */ + public boolean isSet(OptionName name, String value) { + return (values.get(name.optionName + value) != null); + } + + /** + * Check if the value for an undocumented option has not been set. + */ + public boolean isUnset(String name) { + return (values.get(name) == null); + } + + /** + * Check if the value for an option has not been set. + */ + public boolean isUnset(OptionName name) { + return (values.get(name.optionName) == null); + } + + /** + * Check if the value for a choice option has not been set to a specific value. + */ + public boolean isUnset(OptionName name, String value) { + return (values.get(name.optionName + value) == null); + } + public void put(String name, String value) { values.put(name, value); } @@ -92,16 +141,14 @@ public class Options { return values.size(); } - static final String LINT = "-Xlint"; - /** Check for a lint suboption. */ public boolean lint(String s) { // return true if either the specific option is enabled, or // they are all enabled without the specific one being // disabled return - get(LINT + ":" + s)!=null || - (get(LINT)!=null || get(LINT + ":all")!=null) && - get(LINT+":-"+s)==null; + isSet(XLINT_CUSTOM, s) || + (isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) && + isUnset(XLINT_CUSTOM, "-" + s); } } From 9c946f5a9c672af61acaf63c1c9e12628e41c25a Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Fri, 1 Oct 2010 15:10:32 +0400 Subject: [PATCH 60/88] 6829267: Regression test java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java fails in RHEL5 Reviewed-by: art, anthony --- jdk/src/solaris/classes/sun/awt/X11/XToolkit.java | 13 ++++++++++++- .../native/sun/windows/awt_DesktopProperties.cpp | 3 ++- jdk/src/windows/native/sun/windows/awt_Toolkit.cpp | 8 +++++++- jdk/src/windows/native/sun/windows/awt_Toolkit.h | 1 + .../ToolkitPropertyTest_Enable.java | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index fd8622bd694..192a8f568e9 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -1482,8 +1482,19 @@ public final class XToolkit extends UNIXToolkit implements Runnable { try { if (numberOfButtons == 0) { numberOfButtons = getNumberOfButtonsImpl(); + numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons; + //4th and 5th buttons are for wheel and shouldn't be reported as buttons. + //If we have more than 3 physical buttons and a wheel, we report N-2 buttons. + //If we have 3 physical buttons and a wheel, we report 3 buttons. + //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively. + if (numberOfButtons >=5) { + numberOfButtons -= 2; + } else if (numberOfButtons == 4 || numberOfButtons ==5){ + numberOfButtons = 3; + } } - return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons; + //Assume don't have to re-query the number again and again. + return numberOfButtons; } finally { awtUnlock(); } diff --git a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp index a6ad4325481..50d305fd511 100644 --- a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp +++ b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp @@ -505,7 +505,8 @@ void AwtDesktopProperties::GetOtherParameters() { SetIntegerProperty(TEXT("win.drag.width"), cxdrag); SetIntegerProperty(TEXT("win.drag.height"), cydrag); SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2); - SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS)); + SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons()); + SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime()); // BEGIN cross-platform properties diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index ff23a086612..2beb5191bd2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -133,6 +133,8 @@ extern "C" JNIEXPORT jboolean JNICALL AWTIsHeadless() { static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit"); +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2. + UINT AwtToolkit::GetMouseKeyState() { static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON); @@ -2310,5 +2312,9 @@ void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) { JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl (JNIEnv *, jobject self) { - return GetSystemMetrics(SM_CMOUSEBUTTONS); + return AwtToolkit::GetNumberOfButtons(); +} + +UINT AwtToolkit::GetNumberOfButtons() { + return MOUSE_BUTTONS_WINDOWS_SUPPORTED; } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.h b/jdk/src/windows/native/sun/windows/awt_Toolkit.h index 054b607c42b..2a957719337 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h @@ -185,6 +185,7 @@ public: BOOL IsDynamicLayoutActive(); BOOL areExtraMouseButtonsEnabled(); void setExtraMouseButtonsEnabled(BOOL enable); + static UINT GetNumberOfButtons(); INLINE BOOL localPump() { return m_localPump; } INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag diff --git a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java index fa6a41771aa..e6c19830306 100644 --- a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java +++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java @@ -90,7 +90,7 @@ public class ToolkitPropertyTest_Enable extends Frame { int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks(); for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ buttonMasks[i] = InputEvent.getMaskForButton(i+1); - System.out.println("TEST: "+buttonMasks[i]); + System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]); } for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ From f5a046aae8b7d60283d2ec0ccfb1c90ea27766c2 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Fri, 1 Oct 2010 14:36:01 -0400 Subject: [PATCH 61/88] 6988993: Address Findbugs warnings for the use of String Constructor Reviewed-by: ohair --- .../com/sun/rowset/CachedRowSetImpl.java | 6 +- .../com/sun/rowset/FilteredRowSetImpl.java | 2 +- .../com/sun/rowset/JoinRowSetImpl.java | 6 +- .../rowset/internal/CachedRowSetWriter.java | 4 +- .../rowset/internal/WebRowSetXmlWriter.java | 2 +- .../internal/XmlReaderContentHandler.java | 12 ++-- .../classes/javax/sql/rowset/BaseRowSet.java | 14 ++--- .../javax/sql/rowset/RowSetMetaDataImpl.java | 59 +++++++++---------- .../javax/sql/rowset/serial/SerialRef.java | 4 +- .../javax/sql/rowset/serial/SerialStruct.java | 8 +-- 10 files changed, 56 insertions(+), 61 deletions(-) diff --git a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java index 1c8f279a4ad..414476590db 100644 --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -4042,7 +4042,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: - return new String(srcObj.toString()); + return srcObj.toString(); default: throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); } @@ -4139,7 +4139,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: - return new String(srcObj.toString()); + return srcObj.toString(); default: throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); } @@ -6434,7 +6434,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern if (tabName == null) throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString()); else - tableName = new String(tabName); + tableName = tabName; } /** diff --git a/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java index a9becf17d37..4899aef14cd 100644 --- a/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java @@ -1106,7 +1106,7 @@ public class FilteredRowSetImpl extends WebRowSetImpl implements Serializable, C public void updateBytes(int columnIndex , byte []x) throws SQLException { boolean bool; - String val = new String(); + String val = ""; Byte [] obj_arr = new Byte[x.length]; diff --git a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java index a1380586809..8284d855959 100644 --- a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java @@ -876,8 +876,8 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { String strWhereClause = "Select "; String whereClause; - String tabName= null; - String strTabName = null; + String tabName= ""; + String strTabName = ""; int sz,cols; int j; CachedRowSetImpl crs; @@ -891,8 +891,6 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet { // tableNameX.(rowsetX.getMatchColumnName()) == // tableNameZ.(rowsetZ.getMatchColumnName())); - tabName = new String(); - strTabName = new String(); sz = vecRowSetsInJOIN.size(); for(int i=0;iSerialStruct object. */ static final long serialVersionUID = -8322445504027483372L; From b03add14fca1dc2bb65aa59f01a3ae92ac1de31b Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:44:51 -0700 Subject: [PATCH 62/88] Added tag jdk7-b112 for changeset 4dbc2a40aa76 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 19a3f1c2601..ea876d36fc7 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -86,3 +86,4 @@ f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104 81dfc728d7bb7e1fff4a4dc6d0f7cea5a3315667 jdk7-b109 2a02d4a6955c7c078aee9a604cb3be409800d82c jdk7-b110 9702d6fef68e17533ee7fcf5923b11ead3e912ce jdk7-b111 +b852103caf73da70068473777ae867a457bb3ae1 jdk7-b112 From 86b4193a546e65695d255f691c3162a15d7b19e5 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:44:55 -0700 Subject: [PATCH 63/88] Added tag jdk7-b112 for changeset 2212d6ed6562 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 9f6d3054114..8e9d2589f9a 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -86,3 +86,4 @@ a56d734a1e970e1a21a8f4feb13053e9a33674c7 jdk7-b100 c3dd858e09b20206459d9e7b0ead99d27ab00eab jdk7-b109 0e1f80fda2271f53d4bbb59ec3f301dfbcef6a0a jdk7-b110 640fa4d4e2ad4c2d7e4815c955026740d8c52b7a jdk7-b111 +cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a jdk7-b112 From 498a2a778a231c65c5d2a339a4e17fd95e7ffb4c Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:45:01 -0700 Subject: [PATCH 64/88] Added tag jdk7-b112 for changeset 75ef8813e3e2 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 71539d8e572..cc365510f54 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -121,3 +121,4 @@ e44a93947ccbfce712b51725f313163606f15486 jdk7-b108 cc4bb3022b3144dc5db0805b9ef6c7eff2aa3b81 jdk7-b109 2f25f2b8de2700a1822463b1bd3d02b5e218018f jdk7-b110 07b042e13dde4f3479ba9ec55120fcd5e8623323 jdk7-b111 +5511edd5d719f3fc9fdd04879482026a3d2c8652 jdk7-b112 From 76b7afa4ea77e806b913660d71f95290d9a9e957 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:45:06 -0700 Subject: [PATCH 65/88] Added tag jdk7-b112 for changeset 4597d735f40c --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e7b0a593feb..443af650ea0 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -86,3 +86,4 @@ d42c4acb6424a094bdafe2ad9c8c1c7ca7fb7b7e jdk7-b104 0f382d6120fc07aed2209484a42458cabf405916 jdk7-b109 d422dbdd09766269344b796b3a46a5b3f74557e1 jdk7-b110 8106c747067c905d814a737a57fea0e29057b33f jdk7-b111 +1b05254242881527b4d5d711295c0fe708c8823a jdk7-b112 From be3968f8b46c0b09e0e5b36c1dd97b538e7cbcca Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:45:07 -0700 Subject: [PATCH 66/88] Added tag jdk7-b112 for changeset eb3c76a898eb --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 7d3a0bc9d25..7befc114031 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -86,3 +86,4 @@ b1ca39340238a239ba6d8489ad5315215e1366ca jdk7-b108 4f626e0d70bda68c76bbd0e89d2bc2407f979736 jdk7-b109 95ecac35fb11530752bd0404c9bf02bcfb30990e jdk7-b110 2575ebca96c7fb1b78f6ae025a97321210aba309 jdk7-b111 +8e0f0054817f0f73fb33e80fb1333fb45b1d513d jdk7-b112 From fb444f04e23fe89145728f91b97738d15cdecd7e Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:45:14 -0700 Subject: [PATCH 67/88] Added tag jdk7-b112 for changeset 382d78ea38b0 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index e69a21ab6c0..f5bbc9b6da0 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -86,3 +86,4 @@ b91ef6b60f4e19bf4592c6dd594c9bac62487519 jdk7-b106 ab0d3f54a63f2aadfcdd2e14b81f79362ce454e2 jdk7-b109 176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111 +b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112 From ee2df8c3c0fe68320c685b3008638cb63499a258 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Fri, 1 Oct 2010 15:45:26 -0700 Subject: [PATCH 68/88] Added tag jdk7-b112 for changeset c325801e1b17 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index d7bb666b3b3..49a9474e349 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -86,3 +86,4 @@ a408ebb8b3d427dbb3d8ce153dfaeb060564a0a4 jdk7-b108 4826378eaade4c6676c452efe954be4ee113cc11 jdk7-b109 32da0f38d2fe96c558492b8707b40da24643d41e jdk7-b110 8bec624274ef8535720cff553374347c2f4f5fb2 jdk7-b111 +fd2579b80b83bf5d4289426016c7d29174ba5dd9 jdk7-b112 From c299b2e4c08025a232056c3cfeb42cac650d50f9 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Sat, 2 Oct 2010 12:41:20 +0400 Subject: [PATCH 69/88] 6988213: lcms build failure on windows-amd64 Reviewed-by: igor, prr --- jdk/make/sun/cmm/lcms/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdk/make/sun/cmm/lcms/Makefile b/jdk/make/sun/cmm/lcms/Makefile index 1072c2fac7b..702c32680c8 100644 --- a/jdk/make/sun/cmm/lcms/Makefile +++ b/jdk/make/sun/cmm/lcms/Makefile @@ -80,7 +80,12 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR) vpath %.c $(SHARE_SRC)/native/sun/java2d ifeq ($(PLATFORM), windows) -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt +OTHER_CFLAGS += -DCMS_IS_WINDOWS_ + +ifeq ($(COMPILER_VERSION), VS2003) +OTHER_CFLAGS += -Dsqrtf=sqrt +endif + OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \ -I$(SHARE_SRC)/native/sun/awt/debug From afac13bfe2a012c7740b32a12c605f66b840b61b Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sat, 2 Oct 2010 12:59:04 +0100 Subject: [PATCH 70/88] 6979526: (file) java/nio/file/FileStore/Basic.java fails if the same file system is mounted more than once Reviewed-by: kevinw, forax --- .../classes/sun/nio/fs/LinuxFileStore.java | 5 ----- .../classes/sun/nio/fs/SolarisFileStore.java | 5 ----- .../classes/sun/nio/fs/UnixFileStore.java | 21 +++---------------- jdk/test/java/nio/file/FileStore/Basic.java | 2 +- 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java index 1efe13b8199..b8b18f31f09 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java +++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java @@ -156,9 +156,4 @@ class LinuxFileStore return supportsFileAttributeView(UserDefinedFileAttributeView.class); return super.supportsFileAttributeView(name); } - - @Override - boolean isLoopback() { - return false; - } } diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java index 1efa99268c6..efee0d2914b 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java +++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java @@ -108,9 +108,4 @@ class SolarisFileStore return supportsFileAttributeView(UserDefinedFileAttributeView.class); return super.supportsFileAttributeView(name); } - - @Override - boolean isLoopback() { - return type().equals("lofs"); - } } diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java index d1131bc53a9..5ef4cbf6410 100644 --- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java @@ -76,12 +76,6 @@ abstract class UnixFileStore */ abstract UnixMountEntry findMountEntry() throws IOException; - /** - * Returns true if this file store represents a loopback file system that - * will have the same device ID as underlying file system. - */ - abstract boolean isLoopback(); - UnixPath file() { return file; } @@ -169,22 +163,13 @@ abstract class UnixFileStore if (!(ob instanceof UnixFileStore)) return false; UnixFileStore other = (UnixFileStore)ob; - if (dev != other.dev) - return false; - // deviceIDs are equal but they may not be equal if one or both of - // them is a loopback file system - boolean thisIsLoopback = isLoopback(); - if (thisIsLoopback != other.isLoopback()) - return false; // one, but not both, are lofs - if (!thisIsLoopback) - return true; // neither is lofs - // both are lofs so compare mount points - return Arrays.equals(this.entry.dir(), other.entry.dir()); + return (this.dev == other.dev) && + Arrays.equals(this.entry.dir(), other.entry.dir()); } @Override public int hashCode() { - return (int)(dev ^ (dev >>> 32)); + return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir()); } @Override diff --git a/jdk/test/java/nio/file/FileStore/Basic.java b/jdk/test/java/nio/file/FileStore/Basic.java index d85563cf394..9c4a9dbb00b 100644 --- a/jdk/test/java/nio/file/FileStore/Basic.java +++ b/jdk/test/java/nio/file/FileStore/Basic.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6873621 + * @bug 4313887 6873621 6979526 * @summary Unit test for java.nio.file.FileStore * @library .. */ From b44a1bd1052fa556e86fa969acec4c69e091b246 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sun, 3 Oct 2010 19:39:25 +0100 Subject: [PATCH 71/88] 6907737: (file) FileVisitor and Files.walkFileTree issues Reviewed-by: sherman --- .../nio/file/FileSystemLoopException.java | 50 ++++++++++ .../classes/java/nio/file/FileTreeWalker.java | 66 +++++-------- .../java/nio/file/FileVisitOption.java | 6 +- .../classes/java/nio/file/FileVisitor.java | 92 +++++++++---------- .../share/classes/java/nio/file/Files.java | 42 +++++---- .../java/nio/file/SimpleFileVisitor.java | 77 ++++++---------- jdk/src/share/sample/nio/file/Chmod.java | 8 +- jdk/src/share/sample/nio/file/Copy.java | 22 ++--- jdk/src/share/sample/nio/file/WatchDir.java | 10 +- jdk/test/java/nio/file/Files/MaxDepth.java | 67 ++++++++++++++ jdk/test/java/nio/file/Files/Misc.java | 21 +++-- .../java/nio/file/Files/PrintFileTree.java | 31 ++++--- .../java/nio/file/Files/SkipSiblings.java | 14 +-- .../java/nio/file/Files/TerminateWalk.java | 13 +-- .../java/nio/file/Files/WalkWithSecurity.java | 2 +- .../java/nio/file/Files/walk_file_tree.sh | 8 +- jdk/test/java/nio/file/TestUtil.java | 9 +- 17 files changed, 297 insertions(+), 241 deletions(-) create mode 100644 jdk/src/share/classes/java/nio/file/FileSystemLoopException.java create mode 100644 jdk/test/java/nio/file/Files/MaxDepth.java diff --git a/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java new file mode 100644 index 00000000000..fe6beb5ad09 --- /dev/null +++ b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.nio.file; + +/** + * Checked exception thrown when a file system loop, or cycle, is encountered. + * + * @since 1.7 + * @see Files#walkFileTree + */ + +public class FileSystemLoopException + extends FileSystemException +{ + private static final long serialVersionUID = 4843039591949217617L; + + /** + * Constructs an instance of this class. + * + * @param file + * a string identifying the file causing the cycle or {@code null} if + * not known + */ + public FileSystemLoopException(String file) { + super(file); + } +} diff --git a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java index 8086012a9f5..cd45d765290 100644 --- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java +++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java @@ -38,7 +38,6 @@ import sun.nio.fs.BasicFileAttributesHolder; class FileTreeWalker { private final boolean followLinks; - private final boolean detectCycles; private final LinkOption[] linkOptions; private final FileVisitor visitor; private final int maxDepth; @@ -48,17 +47,15 @@ class FileTreeWalker { int maxDepth) { boolean fl = false; - boolean dc = false; for (FileVisitOption option: options) { + // will throw NPE if options contains null switch (option) { - case FOLLOW_LINKS : fl = true; break; - case DETECT_CYCLES : dc = true; break; + case FOLLOW_LINKS : fl = true; break; default: throw new AssertionError("Should not get here"); } } this.followLinks = fl; - this.detectCycles = fl | dc; this.linkOptions = (fl) ? new LinkOption[0] : new LinkOption[] { LinkOption.NOFOLLOW_LINKS }; this.visitor = visitor; @@ -68,13 +65,11 @@ class FileTreeWalker { /** * Walk file tree starting at the given file */ - void walk(Path start) { + void walk(Path start) throws IOException { FileVisitResult result = walk(start, 0, new ArrayList()); - if (result == null) { - throw new NullPointerException("Visitor returned 'null'"); - } + Objects.nonNull(result, "FileVisitor returned null"); } /** @@ -88,11 +83,8 @@ class FileTreeWalker { private FileVisitResult walk(Path file, int depth, List ancestors) + throws IOException { - // depth check - if (depth > maxDepth) - return FileVisitResult.CONTINUE; - // if attributes are cached then use them if possible BasicFileAttributes attrs = null; if ((depth > 0) && @@ -137,13 +129,13 @@ class FileTreeWalker { return visitor.visitFileFailed(file, exc); } - // file is not a directory so invoke visitFile method - if (!attrs.isDirectory()) { + // at maximum depth or file is not a directory + if (depth >= maxDepth || !attrs.isDirectory()) { return visitor.visitFile(file, attrs); } - // check for cycles - if (detectCycles) { + // check for cycles when following links + if (followLinks) { Object key = attrs.fileKey(); // if this directory and ancestor has a file key then we compare @@ -153,19 +145,23 @@ class FileTreeWalker { if (key != null && ancestorKey != null) { if (key.equals(ancestorKey)) { // cycle detected - return visitor.visitFile(file, attrs); + return visitor.visitFileFailed(file, + new FileSystemLoopException(file.toString())); } } else { + boolean isSameFile = false; try { - if (file.isSameFile(ancestor.file())) { - // cycle detected - return visitor.visitFile(file, attrs); - } + isSameFile = file.isSameFile(ancestor.file()); } catch (IOException x) { // ignore } catch (SecurityException x) { // ignore } + if (isSameFile) { + // cycle detected + return visitor.visitFileFailed(file, + new FileSystemLoopException(file.toString())); + } } } @@ -181,7 +177,7 @@ class FileTreeWalker { try { stream = file.newDirectoryStream(); } catch (IOException x) { - return visitor.preVisitDirectoryFailed(file, x); + return visitor.visitFileFailed(file, x); } catch (SecurityException x) { // ignore, as per spec return FileVisitResult.CONTINUE; @@ -192,20 +188,14 @@ class FileTreeWalker { // invoke preVisitDirectory and then visit each entry try { - result = visitor.preVisitDirectory(file); + result = visitor.preVisitDirectory(file, attrs); if (result != FileVisitResult.CONTINUE) { return result; } - // if an I/O occurs during iteration then a CME is thrown. We - // need to distinguish this from a CME thrown by the visitor. - boolean inAction = false; - try { for (Path entry: stream) { - inAction = true; result = walk(entry, depth+1, ancestors); - inAction = false; // returning null will cause NPE to be thrown if (result == null || result == FileVisitResult.TERMINATE) @@ -215,17 +205,9 @@ class FileTreeWalker { if (result == FileVisitResult.SKIP_SIBLINGS) break; } - } catch (ConcurrentModificationException x) { - // if CME thrown because the iteration failed then remember - // the IOException so that it is notified to postVisitDirectory - if (!inAction) { - // iteration failed - Throwable t = x.getCause(); - if (t instanceof IOException) - ioe = (IOException)t; - } - if (ioe == null) - throw x; + } catch (DirectoryIteratorException e) { + // IOException will be notified to postVisitDirectory + ioe = e.getCause(); } } finally { try { @@ -238,7 +220,7 @@ class FileTreeWalker { } finally { // remove key from trail if doing cycle detection - if (detectCycles) { + if (followLinks) { ancestors.remove(ancestors.size()-1); } } diff --git a/jdk/src/share/classes/java/nio/file/FileVisitOption.java b/jdk/src/share/classes/java/nio/file/FileVisitOption.java index 7f1f14013df..8941bd6911a 100644 --- a/jdk/src/share/classes/java/nio/file/FileVisitOption.java +++ b/jdk/src/share/classes/java/nio/file/FileVisitOption.java @@ -37,9 +37,5 @@ public enum FileVisitOption { /** * Follow symbolic links. */ - FOLLOW_LINKS, - /** - * Detect cycles in the file tree. - */ - DETECT_CYCLES; + FOLLOW_LINKS; } diff --git a/jdk/src/share/classes/java/nio/file/FileVisitor.java b/jdk/src/share/classes/java/nio/file/FileVisitor.java index aefc6a8c2d1..06ac0b870fb 100644 --- a/jdk/src/share/classes/java/nio/file/FileVisitor.java +++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java @@ -40,33 +40,28 @@ import java.io.IOException; * Path start = ... * Files.walkFileTree(start, new SimpleFileVisitor<Path>() { * @Override - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - * try { - * file.delete(); - * } catch (IOException exc) { - * // failed to delete, do error handling here - * } + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + * throws IOException + * { + * file.delete(); * return FileVisitResult.CONTINUE; * } * @Override - * public FileVisitResult postVisitDirectory(Path dir, IOException e) { - * if (e == null) { - * try { - * dir.delete(); - * } catch (IOException exc) { - * // failed to delete, do error handling here - * } - * } else { + * public FileVisitResult postVisitDirectory(Path dir, IOException e) + * throws IOException + * { + * if (e != null) { * // directory iteration failed + * throw e; * } + * dir.delete(); * return FileVisitResult.CONTINUE; * } * }); * - *

    Furthermore, suppose we want to copy a file tree rooted at a source - * directory to a target location. In that case, symbolic links should be - * followed and the target directory should be created before the entries in - * the directory are copied. + *

    Furthermore, suppose we want to copy a file tree to a target location. + * In that case, symbolic links should be followed and the target directory + * should be created before the entries in the directory are copied. *

      *     final Path source = ...
      *     final Path target = ...
    @@ -74,25 +69,21 @@ import java.io.IOException;
      *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
      *         new SimpleFileVisitor<Path>() {
      *             @Override
    - *             public FileVisitResult preVisitDirectory(Path dir) {
    + *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
    + *                 throws IOException
    + *             {
      *                 try {
      *                     dir.copyTo(target.resolve(source.relativize(dir)));
      *                 } catch (FileAlreadyExistsException e) {
      *                      // ignore
    - *                 } catch (IOException e) {
    - *                     // copy failed, do error handling here
    - *                     // skip rest of directory and descendants
    - *                     return SKIP_SUBTREE;
      *                 }
      *                 return CONTINUE;
      *             }
      *             @Override
    - *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
    - *                 try {
    - *                     file.copyTo(target.resolve(source.relativize(file)));
    - *                 } catch (IOException e) {
    - *                     // copy failed, do error handling here
    - *                 }
    + *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
    + *                 throws IOException
    + *             {
    + *                 file.copyTo(target.resolve(source.relativize(file)));
      *                 return CONTINUE;
      *             }
      *         });
    @@ -114,22 +105,16 @@ public interface FileVisitor {
          *
          * @param   dir
          *          a reference to the directory
    +     * @param   attrs
    +     *          the directory's basic attributes
          *
          * @return  the visit result
    -     */
    -    FileVisitResult preVisitDirectory(T dir);
    -
    -    /**
    -     * Invoked for a directory that could not be opened.
          *
    -     * @param   dir
    -     *          a reference to the directory
    -     * @param   exc
    -     *          the I/O exception thrown from the attempt to open the directory
    -     *
    -     * @return  the visit result
    +     * @throws  IOException
    +     *          if an I/O error occurs
          */
    -    FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
    +    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
    +        throws IOException;
     
         /**
          * Invoked for a file in a directory.
    @@ -140,21 +125,30 @@ public interface FileVisitor {
          *          the file's basic attributes
          *
          * @return  the visit result
    +     *
    +     * @throws  IOException
    +     *          if an I/O error occurs
          */
    -    FileVisitResult visitFile(T file, BasicFileAttributes attrs);
    +    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
    +        throws IOException;
     
         /**
    -     * Invoked for a file when its basic file attributes could not be read.
    +     * Invoked for a file that could not be visited. This method is invoked
    +     * if the file's attributes could not be read, the file is a directory
    +     * that could not be opened, and other reasons.
          *
          * @param   file
          *          a reference to the file
          * @param   exc
    -     *          the I/O exception thrown from the attempt to read the file
    -     *          attributes
    +     *          the I/O exception that prevented the file from being visited
          *
          * @return  the visit result
    +     *
    +     * @throws  IOException
    +     *          if an I/O error occurs
          */
    -    FileVisitResult visitFileFailed(T file, IOException exc);
    +    FileVisitResult visitFileFailed(T file, IOException exc)
    +        throws IOException;
     
         /**
          * Invoked for a directory after entries in the directory, and all of their
    @@ -171,6 +165,10 @@ public interface FileVisitor {
          *          of the directory to complete prematurely
          *
          * @return  the visit result
    +     *
    +     * @throws  IOException
    +     *          if an I/O error occurs
          */
    -    FileVisitResult postVisitDirectory(T dir, IOException exc);
    +    FileVisitResult postVisitDirectory(T dir, IOException exc)
    +        throws IOException;
     }
    diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java
    index 703a2a82c58..7322016b4c7 100644
    --- a/jdk/src/share/classes/java/nio/file/Files.java
    +++ b/jdk/src/share/classes/java/nio/file/Files.java
    @@ -135,9 +135,9 @@ public final class Files {
          * FileVisitor} invoked for each file encountered. File tree traversal
          * completes when all accessible files in the tree have been visited, or a
          * visit method returns a result of {@link FileVisitResult#TERMINATE
    -     * TERMINATE}. Where a visit method terminates due an uncaught error or
    -     * runtime exception then the traversal is terminated and the error or
    -     * exception is propagated to the caller of this method.
    +     * TERMINATE}. Where a visit method terminates due an {@code IOException},
    +     * an uncaught error, or runtime exception, then the traversal is terminated
    +     * and the error or exception is propagated to the caller of this method.
          *
          * 

    For each file encountered this method attempts to gets its {@link * java.nio.file.attribute.BasicFileAttributes}. If the file is not a @@ -146,12 +146,10 @@ public final class Files { * due to an I/O exception, then the {@link FileVisitor#visitFileFailed * visitFileFailed} method is invoked with the I/O exception. * - *

    Where the file is a directory, this method attempts to open it by - * invoking its {@link Path#newDirectoryStream newDirectoryStream} method. - * Where the directory could not be opened, due to an {@code IOException}, - * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed} - * method is invoked with the I/O exception, after which, the file tree walk - * continues, by default, at the next sibling of the directory. + *

    Where the file is a directory, and the directory could not be opened, + * then the {@code visitFileFailed} method is invoked with the I/O exception, + * after which, the file tree walk continues, by default, at the next + * sibling of the directory. * *

    Where the directory is opened successfully, then the entries in the * directory, and their descendants are visited. When all entries @@ -171,26 +169,25 @@ public final class Files { * method is invoked as specified above). * *

    If the {@code options} parameter contains the {@link - * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link - * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps + * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps * track of directories visited so that cycles can be detected. A cycle * arises when there is an entry in a directory that is an ancestor of the * directory. Cycle detection is done by recording the {@link * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories, * or if file keys are not available, by invoking the {@link Path#isSameFile * isSameFile} method to test if a directory is the same file as an - * ancestor. When a cycle is detected the {@link FileVisitor#visitFile - * visitFile} is invoked with the attributes of the directory. The {@link - * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory} - * method may be used to test if the file is a directory and that a cycle is - * detected. The {@code preVisitDirectory} and {@code postVisitDirectory} - * methods are not invoked. + * ancestor. When a cycle is detected it is treated as an I/O error, and the + * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with + * an instance of {@link FileSystemLoopException}. * *

    The {@code maxDepth} parameter is the maximum number of levels of * directories to visit. A value of {@code 0} means that only the starting * file is visited, unless denied by the security manager. A value of * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all - * levels should be visited. + * levels should be visited. The {@code visitFile} method is invoked for all + * files, including directories, encountered at {@code maxDepth}, unless the + * basic file attributes cannot be read, in which case the {@code + * visitFileFailed} method is invoked. * *

    If a visitor returns a result of {@code null} then {@code * NullPointerException} is thrown. @@ -215,11 +212,14 @@ public final class Files { * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. + * @throws IOException + * If an I/O error is thrown by a visitor method */ public static void walkFileTree(Path start, Set options, int maxDepth, FileVisitor visitor) + throws IOException { if (maxDepth < 0) throw new IllegalArgumentException("'maxDepth' is negative"); @@ -245,8 +245,12 @@ public final class Files { * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. + * @throws IOException + * If an I/O error is thrown by a visitor method */ - public static void walkFileTree(Path start, FileVisitor visitor) { + public static void walkFileTree(Path start, FileVisitor visitor) + throws IOException + { walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, diff --git a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java index 66a2a74f255..77fb516b172 100644 --- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java +++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java @@ -27,7 +27,7 @@ package java.nio.file; import java.nio.file.attribute.BasicFileAttributes; import java.io.IOException; -import java.io.IOError; +import java.util.Objects; /** * A simple visitor of files with default behavior to visit all files and to @@ -47,14 +47,6 @@ public class SimpleFileVisitor implements FileVisitor { protected SimpleFileVisitor() { } - /** - * Throws NullPointerException if obj is null. - */ - private static void checkNotNull(Object obj) { - if (obj == null) - throw new NullPointerException(); - } - /** * Invoked for a directory before entries in the directory are visited. * @@ -62,28 +54,14 @@ public class SimpleFileVisitor implements FileVisitor { * CONTINUE}. */ @Override - public FileVisitResult preVisitDirectory(T dir) { - checkNotNull(dir); + public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) + throws IOException + { + Objects.nonNull(dir); + Objects.nonNull(attrs); return FileVisitResult.CONTINUE; } - /** - * Invoked for a directory that could not be opened. - * - *

    Unless overridden, this method throws {@link IOError} with the I/O - * exception as cause. - * - * @throws IOError - * with the I/O exception thrown when the attempt to open the - * directory failed - */ - @Override - public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) { - checkNotNull(dir); - checkNotNull(exc); - throw new IOError(exc); - } - /** * Invoked for a file in a directory. * @@ -91,27 +69,26 @@ public class SimpleFileVisitor implements FileVisitor { * CONTINUE}. */ @Override - public FileVisitResult visitFile(T file, BasicFileAttributes attrs) { - checkNotNull(file); - checkNotNull(attrs); + public FileVisitResult visitFile(T file, BasicFileAttributes attrs) + throws IOException + { + Objects.nonNull(file); + Objects.nonNull(attrs); return FileVisitResult.CONTINUE; } /** - * Invoked for a file when its basic file attributes could not be read. + * Invoked for a file that could not be visited. * - *

    Unless overridden, this method throws {@link IOError} with the I/O - * exception as cause. - * - * @throws IOError - * with the I/O exception thrown when the attempt to read the file - * attributes failed + *

    Unless overridden, this method re-throws the I/O exception that prevented + * the file from being visited. */ @Override - public FileVisitResult visitFileFailed(T file, IOException exc) { - checkNotNull(file); - checkNotNull(exc); - throw new IOError(exc); + public FileVisitResult visitFileFailed(T file, IOException exc) + throws IOException + { + Objects.nonNull(file); + throw exc; } /** @@ -120,18 +97,16 @@ public class SimpleFileVisitor implements FileVisitor { * *

    Unless overridden, this method returns {@link FileVisitResult#CONTINUE * CONTINUE} if the directory iteration completes without an I/O exception; - * otherwise this method throws {@link IOError} with the I/O exception as - * cause. - * - * @throws IOError - * with the I/O exception thrown when iteration of the directory - * completed prematurely due to an I/O error + * otherwise this method re-throws the I/O exception that caused the iteration + * of the directory to terminate prematurely. */ @Override - public FileVisitResult postVisitDirectory(T dir, IOException exc) { - checkNotNull(dir); + public FileVisitResult postVisitDirectory(T dir, IOException exc) + throws IOException + { + Objects.nonNull(dir); if (exc != null) - throw new IOError(exc); + throw exc; return FileVisitResult.CONTINUE; } } diff --git a/jdk/src/share/sample/nio/file/Chmod.java b/jdk/src/share/sample/nio/file/Chmod.java index 235d1ef1d7c..fd5cd918526 100644 --- a/jdk/src/share/sample/nio/file/Chmod.java +++ b/jdk/src/share/sample/nio/file/Chmod.java @@ -285,17 +285,11 @@ public class Chmod { } @Override - public FileVisitResult preVisitDirectory(FileRef dir) { + public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) { chmod(dir, changer); return CONTINUE; } - @Override - public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) { - System.err.println("WARNING: " + exc); - return CONTINUE; - } - @Override public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) { chmod(file, changer); diff --git a/jdk/src/share/sample/nio/file/Copy.java b/jdk/src/share/sample/nio/file/Copy.java index 2c087062a7d..5408e6a5cbc 100644 --- a/jdk/src/share/sample/nio/file/Copy.java +++ b/jdk/src/share/sample/nio/file/Copy.java @@ -85,7 +85,7 @@ public class Copy { } @Override - public FileVisitResult preVisitDirectory(Path dir) { + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { // before visiting entries in a directory we copy the directory // (okay if directory already exists). CopyOption[] options = (preserve) ? @@ -103,20 +103,10 @@ public class Copy { return CONTINUE; } - @Override - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) { - System.err.format("Unable to copy: %s: %s%n", dir, exc); - return CONTINUE; - } - @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - if (attrs.isDirectory()) { - System.err.println("cycle detected: " + file); - } else { - copyFile(file, target.resolve(source.relativize(file)), - prompt, preserve); - } + copyFile(file, target.resolve(source.relativize(file)), + prompt, preserve); return CONTINUE; } @@ -137,7 +127,11 @@ public class Copy { @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { - System.err.format("Unable to copy: %s: %s%n", file, exc); + if (exc instanceof FileSystemLoopException) { + System.err.println("cycle detected: " + file); + } else { + System.err.format("Unable to copy: %s: %s%n", file, exc); + } return CONTINUE; } } diff --git a/jdk/src/share/sample/nio/file/WatchDir.java b/jdk/src/share/sample/nio/file/WatchDir.java index 8a9b889ec00..73b4b7052fd 100644 --- a/jdk/src/share/sample/nio/file/WatchDir.java +++ b/jdk/src/share/sample/nio/file/WatchDir.java @@ -78,12 +78,10 @@ public class WatchDir { // register directory and sub-directories Files.walkFileTree(start, new SimpleFileVisitor() { @Override - public FileVisitResult preVisitDirectory(Path dir) { - try { - register(dir); - } catch (IOException x) { - throw new IOError(x); - } + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + throws IOException + { + register(dir); return FileVisitResult.CONTINUE; } }); diff --git a/jdk/test/java/nio/file/Files/MaxDepth.java b/jdk/test/java/nio/file/Files/MaxDepth.java new file mode 100644 index 00000000000..a895238d518 --- /dev/null +++ b/jdk/test/java/nio/file/Files/MaxDepth.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.io.IOException; +import java.util.*; + +/** + * Unit test for Files.walkFileTree to test maxDepth parameter + */ + +public class MaxDepth { + public static void main(String[] args) throws Exception { + final Path top = Paths.get(args[0]); + + for (int i=0; i<5; i++) { + Set opts = Collections.emptySet(); + final int maxDepth = i; + Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor() { + // compute depth based on relative path to top directory + private int depth(Path file) { + Path rp = file.relativize(top); + return (rp == null) ? 0 : rp.getNameCount(); + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + int d = depth(dir); + if (d == maxDepth) + throw new RuntimeException("Should not open directories at maxDepth"); + if (d > maxDepth) + throw new RuntimeException("Too deep"); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + int d = depth(file); + if (d > maxDepth) + throw new RuntimeException("Too deep"); + return FileVisitResult.CONTINUE; + } + }); + } + } +} diff --git a/jdk/test/java/nio/file/Files/Misc.java b/jdk/test/java/nio/file/Files/Misc.java index d722f7245cc..89e7c251a8d 100644 --- a/jdk/test/java/nio/file/Files/Misc.java +++ b/jdk/test/java/nio/file/Files/Misc.java @@ -30,6 +30,7 @@ import java.nio.file.*; import java.nio.file.attribute.Attributes; +import java.nio.file.attribute.BasicFileAttributes; import java.io.IOException; import java.util.*; @@ -117,25 +118,25 @@ public class Misc { SimpleFileVisitor visitor = new SimpleFileVisitor() { }; boolean ranTheGauntlet = false; - try { visitor.preVisitDirectory(null); + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get(".")); + + try { visitor.preVisitDirectory(null, attrs); } catch (NullPointerException x0) { - try { visitor.preVisitDirectoryFailed(null, new IOException()); + try { visitor.preVisitDirectory(dir, null); } catch (NullPointerException x1) { - try { visitor.preVisitDirectoryFailed(dir, null); + try { visitor.visitFile(null, attrs); } catch (NullPointerException x2) { - try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get("."))); - } catch (NullPointerException x3) { try { visitor.visitFile(dir, null); - } catch (NullPointerException x4) { + } catch (NullPointerException x3) { try { visitor.visitFileFailed(null, new IOException()); - } catch (NullPointerException x5) { + } catch (NullPointerException x4) { try { visitor.visitFileFailed(dir, null); - } catch (NullPointerException x6) { + } catch (NullPointerException x5) { try { visitor.postVisitDirectory(null, new IOException()); - } catch (NullPointerException x7) { + } catch (NullPointerException x6) { // if we get here then all visit* methods threw NPE as expected ranTheGauntlet = true; - }}}}}}}} + }}}}}}} if (!ranTheGauntlet) throw new RuntimeException("A visit method did not throw NPE"); } diff --git a/jdk/test/java/nio/file/Files/PrintFileTree.java b/jdk/test/java/nio/file/Files/PrintFileTree.java index 044da8fec78..fdc17cdef3a 100644 --- a/jdk/test/java/nio/file/Files/PrintFileTree.java +++ b/jdk/test/java/nio/file/Files/PrintFileTree.java @@ -56,29 +56,34 @@ public class PrintFileTree { final boolean reportCycles = printCycles; Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor() { - public FileVisitResult preVisitDirectory(FileRef dir) { + @Override + public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) { System.out.println(dir); return FileVisitResult.CONTINUE; } - public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) { - exc.printStackTrace(); - return FileVisitResult.CONTINUE; - } + @Override public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) { if (!attrs.isDirectory() || reportCycles) System.out.println(file); return FileVisitResult.CONTINUE; } - public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) { - if (exc != null) { - exc.printStackTrace(); - return FileVisitResult.TERMINATE; - } + @Override + public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) + throws IOException + { + if (exc != null) + throw exc; return FileVisitResult.CONTINUE; } - public FileVisitResult visitFileFailed(FileRef file, IOException exc) { - exc.printStackTrace(); - return FileVisitResult.TERMINATE; + @Override + public FileVisitResult visitFileFailed(FileRef file, IOException exc) + throws IOException + { + if (reportCycles && (exc instanceof FileSystemLoopException)) { + System.out.println(file); + return FileVisitResult.CONTINUE; + } + throw exc; } }); } diff --git a/jdk/test/java/nio/file/Files/SkipSiblings.java b/jdk/test/java/nio/file/Files/SkipSiblings.java index 952fdea49fa..5cd7e34ac90 100644 --- a/jdk/test/java/nio/file/Files/SkipSiblings.java +++ b/jdk/test/java/nio/file/Files/SkipSiblings.java @@ -54,32 +54,28 @@ public class SkipSiblings { public static void main(String[] args) throws Exception { Path dir = Paths.get(args[0]); - Files.walkFileTree(dir, new FileVisitor() { - public FileVisitResult preVisitDirectory(Path dir) { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { check(dir); if (skip(dir)) return FileVisitResult.SKIP_SIBLINGS; return FileVisitResult.CONTINUE; } - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) { - throw new RuntimeException(exc); - } - + @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { check(file); if (skip(file)) return FileVisitResult.SKIP_SIBLINGS; return FileVisitResult.CONTINUE; } + @Override public FileVisitResult postVisitDirectory(Path dir, IOException x) { if (x != null) throw new RuntimeException(x); check(dir); return FileVisitResult.CONTINUE; } - public FileVisitResult visitFileFailed(Path file, IOException x) { - throw new RuntimeException(x); - } }); } } diff --git a/jdk/test/java/nio/file/Files/TerminateWalk.java b/jdk/test/java/nio/file/Files/TerminateWalk.java index 5299b87818e..b2858c450ac 100644 --- a/jdk/test/java/nio/file/Files/TerminateWalk.java +++ b/jdk/test/java/nio/file/Files/TerminateWalk.java @@ -49,22 +49,19 @@ public class TerminateWalk { public static void main(String[] args) throws Exception { Path dir = Paths.get(args[0]); - Files.walkFileTree(dir, new FileVisitor() { - public FileVisitResult preVisitDirectory(Path dir) { - return maybeTerminate(); - } - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { return maybeTerminate(); } + @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { return maybeTerminate(); } + @Override public FileVisitResult postVisitDirectory(Path dir, IOException x) { return maybeTerminate(); } - public FileVisitResult visitFileFailed(Path file, IOException x) { - return maybeTerminate(); - } }); } } diff --git a/jdk/test/java/nio/file/Files/WalkWithSecurity.java b/jdk/test/java/nio/file/Files/WalkWithSecurity.java index f4386190c43..9044398b6ab 100644 --- a/jdk/test/java/nio/file/Files/WalkWithSecurity.java +++ b/jdk/test/java/nio/file/Files/WalkWithSecurity.java @@ -116,7 +116,7 @@ public class WalkWithSecurity { } @Override - public FileVisitResult preVisitDirectory(Path dir) { + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { System.out.println(dir); count++; return FileVisitResult.CONTINUE; diff --git a/jdk/test/java/nio/file/Files/walk_file_tree.sh b/jdk/test/java/nio/file/Files/walk_file_tree.sh index 50d141f878a..4f41d3cc036 100644 --- a/jdk/test/java/nio/file/Files/walk_file_tree.sh +++ b/jdk/test/java/nio/file/Files/walk_file_tree.sh @@ -22,9 +22,9 @@ # # @test -# @bug 4313887 +# @bug 4313887 6907737 # @summary Unit test for walkFileTree method -# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk +# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth # @run shell walk_file_tree.sh # if TESTJAVA isn't set then we assume an interactive run. @@ -84,6 +84,10 @@ if [ $? != 0 ]; then failures=`expr $failures + 1`; fi $JAVA TerminateWalk "$ROOT" if [ $? != 0 ]; then failures=`expr $failures + 1`; fi +# test maxDepth +$JAVA MaxDepth "$ROOT" +if [ $? != 0 ]; then failures=`expr $failures + 1`; fi + # clean-up rm -r "$ROOT" diff --git a/jdk/test/java/nio/file/TestUtil.java b/jdk/test/java/nio/file/TestUtil.java index 753a4cdd3c5..c6acccd1ea0 100644 --- a/jdk/test/java/nio/file/TestUtil.java +++ b/jdk/test/java/nio/file/TestUtil.java @@ -44,15 +44,10 @@ public class TestUtil { return createTemporaryDirectory(System.getProperty("java.io.tmpdir")); } - static void removeAll(Path dir) { + static void removeAll(Path dir) throws IOException { Files.walkFileTree(dir, new FileVisitor() { @Override - public FileVisitResult preVisitDirectory(Path dir) { - return FileVisitResult.CONTINUE; - } - @Override - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) { - System.err.format("Error occured accessing directory %s\n", dir, exc); + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { return FileVisitResult.CONTINUE; } @Override From ca93e7004f70148bdc0c831a49a42551d17117c3 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sun, 3 Oct 2010 19:40:15 +0100 Subject: [PATCH 72/88] 6907737: (file) FileVisitor and Files.walkFileTree issues Reviewed-by: jjg --- .../classes/com/sun/tools/javac/nio/JavacPathFileManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java index 66fd4c996f9..1181c274e71 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java @@ -366,11 +366,11 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan // } // } int maxDepth = (recurse ? Integer.MAX_VALUE : 1); - Set opts = EnumSet.of(DETECT_CYCLES, FOLLOW_LINKS); + Set opts = EnumSet.of(FOLLOW_LINKS); Files.walkFileTree(packageDir, opts, maxDepth, new SimpleFileVisitor() { @Override - public FileVisitResult preVisitDirectory(Path dir) { + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292? return FileVisitResult.CONTINUE; else From 2588620965fd9df456fc8aa5febd44c8482b74e9 Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu Date: Mon, 4 Oct 2010 13:05:14 +0900 Subject: [PATCH 73/88] 6955776: (tz) Windows-only: tzmappings needs update for KB981793 6929185: (tz) Windows-only: tzmappings needs update for KB979306 Reviewed-by: peytoia --- jdk/src/windows/lib/tzmappings | 50 ++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/jdk/src/windows/lib/tzmappings b/jdk/src/windows/lib/tzmappings index 05309c9aef8..bbc3ca09ce2 100644 --- a/jdk/src/windows/lib/tzmappings +++ b/jdk/src/windows/lib/tzmappings @@ -1,5 +1,4 @@ # -# # This file describes mapping information between Windows and Java # time zones. # Format: Each line should include a colon separated fields of Windows @@ -11,7 +10,7 @@ # NOTE # This table format is not a public interface of any Java # platforms. No applications should depend on this file in any form. -# +# # This table has been generated by a program and should not be edited # manually. # @@ -84,8 +83,8 @@ Ekaterinburg:10,11::Asia/Yekaterinburg: Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg: West Asia:10,11:UZ:Asia/Tashkent: West Asia Standard Time:10,11:UZ:Asia/Tashkent: -Central Asia:12,13::Asia/Dhaka: -Central Asia Standard Time:12,13::Asia/Dhaka: +Central Asia:12,13::Asia/Almaty: +Central Asia Standard Time:12,13::Asia/Almaty: N. Central Asia Standard Time:12,13::Asia/Novosibirsk: Bangkok:14,15::Asia/Bangkok: Bangkok Standard Time:14,15::Asia/Bangkok: @@ -167,22 +166,27 @@ Greenwich:88,89::GMT: Greenwich Standard Time:88,89::GMT: Argentina Standard Time:900,900::America/Buenos_Aires: Azerbaijan Standard Time:901,901:AZ:Asia/Baku: -Central Brazilian Standard Time:902,902:BR:America/Manaus: -Central Standard Time (Mexico):903,903::America/Mexico_City: -Georgian Standard Time:904,904:GE:Asia/Tbilisi: -Jordan Standard Time:905,905:JO:Asia/Amman: -Mauritius Standard Time:906,906:MU:Indian/Mauritius: -Middle East Standard Time:907,907:LB:Asia/Beirut: -Montevideo Standard Time:908,908:UY:America/Montevideo: -Morocco Standard Time:909,909:MA:Africa/Casablanca: -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua: -Namibia Standard Time:911,911:NA:Africa/Windhoek: -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana: -Pakistan Standard Time:913,913::Asia/Karachi: -UTC:914,914::UTC: -Venezuela Standard Time:915,915::America/Caracas: -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka: -Paraguay Standard Time:917,917:PY:America/Asuncion: -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco: -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar: -Armenian Standard Time:920,920:AM:Asia/Yerevan: +Bangladesh Standard Time:902,902::Asia/Dhaka: +Central Brazilian Standard Time:903,903:BR:America/Manaus: +Central Standard Time (Mexico):904,904::America/Mexico_City: +Georgian Standard Time:905,905:GE:Asia/Tbilisi: +Jordan Standard Time:906,906:JO:Asia/Amman: +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka: +Mauritius Standard Time:908,908:MU:Indian/Mauritius: +Middle East Standard Time:909,909:LB:Asia/Beirut: +Montevideo Standard Time:910,910:UY:America/Montevideo: +Morocco Standard Time:911,911:MA:Africa/Casablanca: +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua: +Namibia Standard Time:913,913:NA:Africa/Windhoek: +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana: +Pakistan Standard Time:915,915::Asia/Karachi: +Paraguay Standard Time:916,916:PY:America/Asuncion: +Syria Standard Time:917,917:SY:Asia/Damascus: +UTC:918,918::UTC: +UTC+12:919,919::GMT+1200: +UTC-02:920,920::GMT-0200: +UTC-11:921,921::GMT-1100: +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar: +Venezuela Standard Time:923,923::America/Caracas: +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco: +Armenian Standard Time:925,925:AM:Asia/Yerevan: From fbb62aa5664f8a30c87051624907ea1bc068d81d Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Mon, 4 Oct 2010 11:40:07 +0400 Subject: [PATCH 74/88] 6847155: test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java fails Reviewed-by: denis --- .../MouseModifiersUnitTest_Extra.java | 100 +++++++++--------- 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java index f70b8dd691b..0571820837d 100644 --- a/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java +++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java @@ -21,16 +21,15 @@ public class MouseModifiersUnitTest_Extra extends Frame { static final int SHIFT = 1; static final int CTRL = 2; static final int ALT = 3; - static CheckingModifierAdapter adapterTest1; - static CheckingModifierAdapter adapterTest2; - static CheckingModifierAdapter adapterTest3; - static CheckingModifierAdapter adapterTest4; + static CheckingModifierAdapterExtra adapterTest1; + static CheckingModifierAdapterExtra adapterTest2; + static CheckingModifierAdapterExtra adapterTest3; + static CheckingModifierAdapterExtra adapterTest4; static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception static boolean autorun = false; //use robot or manual run static int testModifier = NONE; - static int [] mouseButtons; static int [] mouseButtonDownMasks; //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them @@ -39,7 +38,6 @@ public class MouseModifiersUnitTest_Extra extends Frame { static int [] modifiersExStandardCTRL; static int [] modifiersExStandardALT; - // final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK}; // BUTTON1, 2, 3 press-release. final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK; @@ -56,7 +54,7 @@ public class MouseModifiersUnitTest_Extra extends Frame { if (modifiersEx != curStandardExModifiers[index]){ // System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers"); - MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -168,7 +166,7 @@ public class MouseModifiersUnitTest_Extra extends Frame { } if (modifiersEx != curStandardExModifiers[index]){ - MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -191,7 +189,7 @@ public class MouseModifiersUnitTest_Extra extends Frame { } if (modifiersEx != curStandardExModifiers[index]){ - MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -275,11 +273,11 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest1); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ - System.out.println("testNONE() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + for (int i = 3; i< mouseButtonDownMasks.length; i++){ + System.out.println("testNONE() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); } robot.delay(1000); this.removeMouseListener(adapterTest1); @@ -289,12 +287,12 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest2); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_SHIFT); - System.out.println("testSHIFT() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_SHIFT); } robot.delay(1000); @@ -305,12 +303,12 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest3); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_CONTROL); - System.out.println("testCTRL() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testCTRL() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_CONTROL); } robot.delay(1000); @@ -321,12 +319,12 @@ public class MouseModifiersUnitTest_Extra extends Frame { this.addMouseListener(adapterTest4); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_ALT); - System.out.println("testALT() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testALT() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_ALT); } robot.delay(1000); @@ -368,52 +366,52 @@ public class MouseModifiersUnitTest_Extra extends Frame { } public static void initAdapters(){ - adapterTest1 = new CheckingModifierAdapter(NONE); - adapterTest2 = new CheckingModifierAdapter(SHIFT); - adapterTest3 = new CheckingModifierAdapter(CTRL); - adapterTest4 = new CheckingModifierAdapter(ALT); + adapterTest1 = new CheckingModifierAdapterExtra(NONE); + adapterTest2 = new CheckingModifierAdapterExtra(SHIFT); + adapterTest3 = new CheckingModifierAdapterExtra(CTRL); + adapterTest4 = new CheckingModifierAdapterExtra(ALT); } public static void initVars(){ - int [] tmp = new int [MouseInfo.getNumberOfButtons()]; - for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ - tmp[i] = InputEvent.getMaskForButton(i+1); - // System.out.println("TEST: "+tmp[i]); + //Init the array of the mouse button masks. It will be used for generating mouse events. + mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()]; + for (int i = 0; i < mouseButtonDownMasks.length; i++){ + mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1); + System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]); } - mouseButtons = Arrays.copyOf(tmp, tmp.length); - - for (int i = 0; i < mouseButtons.length; i++){ - System.out.println("MouseArray [i] == "+mouseButtons[i]); - } - - mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length); - // So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3" // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK. - tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; - Arrays.fill(tmp, 0); + int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; + //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys) + Arrays.fill(tmp, 0); for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ tmp[i] = mouseButtonDownMasks[j]; } modifiersExStandard = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length); } @@ -436,9 +434,9 @@ public class MouseModifiersUnitTest_Extra extends Frame { /* A class that invoke appropriate verification * routine with current modifier. */ -class CheckingModifierAdapter extends MouseAdapter{ +class CheckingModifierAdapterExtra extends MouseAdapter{ int modifier; - public CheckingModifierAdapter(int modifier){ + public CheckingModifierAdapterExtra(int modifier){ this.modifier = modifier; } From afc679f6adf40e9a1306aa838e3ca29acbbf40f4 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Mon, 4 Oct 2010 16:12:07 +0400 Subject: [PATCH 75/88] 6987233: FileDialog.getDirectory() should add a trainling slash when GTK FileDialog is used Add the trailing slash if it's absent Reviewed-by: art, dcherepanov --- jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java index ba2b78c4e0e..57a0492ddee 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java @@ -64,7 +64,10 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { accessor.setFile(fd, null); accessor.setFiles(fd, null, null); } else { - accessor.setDirectory(fd, directory); + // Fix 6987233: add the trailing slash if it's absent + accessor.setDirectory(fd, directory + + (directory.endsWith(File.separator) ? + "" : File.separator)); accessor.setFile(fd, filenames[0]); accessor.setFiles(fd, directory, filenames); } From 8aee53f1b5c59b62a380d625696744f9d79566f0 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Mon, 4 Oct 2010 16:21:26 +0400 Subject: [PATCH 76/88] 6982279: java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java failed due to NPE Rely on the WWindowPeer.getTranslucentGraphics()'s return value Reviewed-by: art, dcherepanov --- .../sun/awt/windows/WComponentPeer.java | 30 ++++++++++--------- .../classes/sun/awt/windows/WWindowPeer.java | 10 ------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java index d697fd34047..5a3cd2ddd87 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java @@ -556,24 +556,26 @@ public abstract class WComponentPeer extends WObjectPeer Component target = (Component)getTarget(); Window window = SunToolkit.getContainingWindow(target); - if (window != null && !window.isOpaque()) { - // Non-opaque windows do not support heavyweight children. - // Redirect all painting to the Window's Graphics instead. - // The caller is responsible for calling the - // WindowPeer.updateWindow() after painting has finished. - int x = 0, y = 0; - for (Component c = target; c != window; c = c.getParent()) { - x += c.getX(); - y += c.getY(); - } - + if (window != null) { Graphics g = ((WWindowPeer)window.getPeer()).getTranslucentGraphics(); + // getTranslucentGraphics() returns non-null value for non-opaque windows only + if (g != null) { + // Non-opaque windows do not support heavyweight children. + // Redirect all painting to the Window's Graphics instead. + // The caller is responsible for calling the + // WindowPeer.updateWindow() after painting has finished. + int x = 0, y = 0; + for (Component c = target; c != window; c = c.getParent()) { + x += c.getX(); + y += c.getY(); + } - g.translate(x, y); - g.clipRect(0, 0, target.getWidth(), target.getHeight()); + g.translate(x, y); + g.clipRect(0, 0, target.getWidth(), target.getHeight()); - return g; + return g; + } } SurfaceData surfaceData = this.surfaceData; diff --git a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java index c5c979e34ec..d3ccd4db4d9 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -594,16 +594,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, } } - @Override - public Graphics getGraphics() { - synchronized (getStateLock()) { - if (!isOpaque) { - return getTranslucentGraphics(); - } - } - return super.getGraphics(); - } - @Override public void setBackground(Color c) { super.setBackground(c); From 41cc1e2f4a94c476d05cd9bda6ef1e183013b33c Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 4 Oct 2010 14:17:36 +0100 Subject: [PATCH 77/88] 6989190: SO_SNDBUF/SO_RCVBUF limits should only be checked when setsockopt fails (sol) Reviewed-by: chegar, michaelm --- jdk/src/solaris/native/java/net/net_util_md.c | 26 +++++++++---- .../Basic.java | 38 +++++++++++++++++++ .../AsynchronousSocketChannel/Basic.java | 16 +++++++- .../DatagramChannel/SocketOptionTests.java | 13 ++++++- .../SocketOptionTests.java | 4 ++ .../SocketChannel/SocketOptionTests.java | 9 +++++ 6 files changed, 94 insertions(+), 12 deletions(-) diff --git a/jdk/src/solaris/native/java/net/net_util_md.c b/jdk/src/solaris/native/java/net/net_util_md.c index 8a414e60141..43baab96ea8 100644 --- a/jdk/src/solaris/native/java/net/net_util_md.c +++ b/jdk/src/solaris/native/java/net/net_util_md.c @@ -363,17 +363,20 @@ void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, const char* hostname, int gai_error) { + int size; + char *buf; const char *format = "%s: %s"; const char *error_string = (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error); if (error_string == NULL) error_string = "unknown error"; - int size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; - char *buf = (char *) malloc(size); + size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; + buf = (char *) malloc(size); if (buf) { + jstring s; sprintf(buf, format, hostname, error_string); - jstring s = JNU_NewStringPlatform(env, buf); + s = JNU_NewStringPlatform(env, buf); if (s != NULL) { jobject x = JNU_NewObjectByName(env, "java/net/UnknownHostException", @@ -1203,19 +1206,26 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg, } /* - * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to - * ensure that value is <= max_buf as otherwise we get - * an invalid argument. + * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp + * the value when it exceeds the system limit. */ #ifdef __solaris__ if (level == SOL_SOCKET) { if (opt == SO_SNDBUF || opt == SO_RCVBUF) { int sotype, arglen; int *bufsize, maxbuf; + int ret; + + /* Attempt with the original size */ + ret = setsockopt(fd, level, opt, arg, len); + if ((ret == 0) || (ret == -1 && errno != ENOBUFS)) + return ret; + + /* Exceeded system limit so clamp and retry */ if (!init_max_buf) { - tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024); - udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024); + tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024); + udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024); init_max_buf = 1; } diff --git a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java index 54c0b0ea723..e526112ae26 100644 --- a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java @@ -29,7 +29,9 @@ import java.nio.channels.*; import java.net.*; +import static java.net.StandardSocketOption.*; import java.io.IOException; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; @@ -39,6 +41,7 @@ public class Basic { public static void main(String[] args) throws Exception { testBind(); testAccept(); + testSocketOptions(); } static void testBind() throws Exception { @@ -131,4 +134,39 @@ public class Basic { } } + + static void testSocketOptions() throws Exception { + System.out.println("-- socket options --"); + AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open(); + try { + // check supported options + Set> options = ch.supportedOptions(); + if (!options.contains(SO_REUSEADDR)) + throw new RuntimeException("SO_REUSEADDR should be supported"); + if (!options.contains(SO_RCVBUF)) + throw new RuntimeException("SO_RCVBUF should be supported"); + + // allowed to change when not bound + ch.setOption(SO_RCVBUF, 256*1024); // can't check + int before = ch.getOption(SO_RCVBUF); + int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_RCVBUF to decrease"); + ch.setOption(SO_REUSEADDR, true); + checkOption(ch, SO_REUSEADDR, true); + ch.setOption(SO_REUSEADDR, false); + checkOption(ch, SO_REUSEADDR, false); + } finally { + ch.close(); + } + } + + static void checkOption(AsynchronousServerSocketChannel ch, + SocketOption name, Object expectedValue) + throws IOException + { + Object value = ch.getOption(name); + if (!value.equals(expectedValue)) + throw new RuntimeException("value not as expected"); + } } diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java index df12b258ce1..e8f23f46866 100644 --- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java +++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java @@ -121,8 +121,20 @@ public class Basic { AsynchronousSocketChannel ch = AsynchronousSocketChannel.open() .setOption(SO_RCVBUF, 128*1024) .setOption(SO_SNDBUF, 128*1024) - .setOption(SO_REUSEADDR, true) - .bind(new InetSocketAddress(0)); + .setOption(SO_REUSEADDR, true); + + // check SO_SNDBUF/SO_RCVBUF limits + int before, after; + before = ch.getOption(SO_SNDBUF); + after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_SNDBUF to decrease"); + before = ch.getOption(SO_RCVBUF); + after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_RCVBUF to decrease"); + + ch.bind(new InetSocketAddress(0)); // default values if ((Boolean)ch.getOption(SO_KEEPALIVE)) diff --git a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java index cbd6b1468a9..e09fd8c09aa 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java +++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java @@ -68,8 +68,17 @@ public class SocketOptionTests { checkOption(dc, SO_BROADCAST, true); dc.setOption(SO_BROADCAST, false); checkOption(dc, SO_BROADCAST, false); - dc.setOption(SO_SNDBUF, 16*1024); // can't check - dc.setOption(SO_RCVBUF, 16*1024); // can't check + dc.setOption(SO_SNDBUF, 128*1024); // can't check + dc.setOption(SO_RCVBUF, 128*1024); // can't check + int before, after; + before = dc.getOption(SO_SNDBUF); + after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_SNDBUF to decrease"); + before = dc.getOption(SO_RCVBUF); + after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_RCVBUF to decrease"); dc.setOption(SO_REUSEADDR, true); checkOption(dc, SO_REUSEADDR, true); dc.setOption(SO_REUSEADDR, false); diff --git a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java index 8d30e3a1809..d5ad22687d1 100644 --- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java +++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java @@ -56,6 +56,10 @@ public class SocketOptionTests { // allowed to change when not bound ssc.setOption(SO_RCVBUF, 256*1024); // can't check + int before = ssc.getOption(SO_RCVBUF); + int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_RCVBUF to decrease"); ssc.setOption(SO_REUSEADDR, true); checkOption(ssc, SO_REUSEADDR, true); ssc.setOption(SO_REUSEADDR, false); diff --git a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java index 89bbfcafc1a..9fe1abddef4 100644 --- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java +++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java @@ -70,6 +70,15 @@ public class SocketOptionTests { checkOption(sc, SO_KEEPALIVE, false); sc.setOption(SO_SNDBUF, 128*1024); // can't check sc.setOption(SO_RCVBUF, 256*1024); // can't check + int before, after; + before = sc.getOption(SO_SNDBUF); + after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_SNDBUF to decrease"); + before = sc.getOption(SO_RCVBUF); + after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF); + if (after < before) + throw new RuntimeException("setOption caused SO_RCVBUF to decrease"); sc.setOption(SO_REUSEADDR, true); checkOption(sc, SO_REUSEADDR, true); sc.setOption(SO_REUSEADDR, false); From 0c5307c12be4c3c6f4be7eea4d6feb73a5d915a2 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Mon, 4 Oct 2010 13:04:09 -0400 Subject: [PATCH 78/88] 6989139: Address JDBC Findbugs where Number type Constructor are used Reviewed-by: ohair --- .../com/sun/rowset/CachedRowSetImpl.java | 60 ++++++------- .../com/sun/rowset/FilteredRowSetImpl.java | 12 +-- .../com/sun/rowset/JdbcRowSetImpl.java | 20 ++--- .../com/sun/rowset/JoinRowSetImpl.java | 2 +- .../rowset/internal/CachedRowSetWriter.java | 20 ++--- .../rowset/internal/WebRowSetXmlWriter.java | 4 +- .../internal/XmlReaderContentHandler.java | 10 +-- .../classes/javax/sql/rowset/BaseRowSet.java | 84 +++++++++---------- .../sql/rowset/serial/SQLOutputImpl.java | 12 +-- .../javax/sql/rowset/serial/SerialRef.java | 2 +- 10 files changed, 113 insertions(+), 113 deletions(-) diff --git a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java index 414476590db..cce2997202b 100644 --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -525,7 +525,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -1299,7 +1299,7 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern tMap = new TreeMap(); for (int i = 0; i Date: Thu, 7 Oct 2010 15:12:00 -0700 Subject: [PATCH 79/88] Added tag jdk7-b113 for changeset 584eae2875f4 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index ea876d36fc7..91c72f80940 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -87,3 +87,4 @@ f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104 2a02d4a6955c7c078aee9a604cb3be409800d82c jdk7-b110 9702d6fef68e17533ee7fcf5923b11ead3e912ce jdk7-b111 b852103caf73da70068473777ae867a457bb3ae1 jdk7-b112 +c1df968c4527bfab5f97662a89245f15d12d378b jdk7-b113 From 70757fa2697a3f40f2dc39a2448b9ab0183c9ec3 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 7 Oct 2010 15:12:01 -0700 Subject: [PATCH 80/88] Added tag jdk7-b113 for changeset c180f52ae197 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 8e9d2589f9a..03eadfbbb1b 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -87,3 +87,4 @@ c3dd858e09b20206459d9e7b0ead99d27ab00eab jdk7-b109 0e1f80fda2271f53d4bbb59ec3f301dfbcef6a0a jdk7-b110 640fa4d4e2ad4c2d7e4815c955026740d8c52b7a jdk7-b111 cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a jdk7-b112 +a89a6c5be9d1a754868d3d359cbf7ad36aa95631 jdk7-b113 From b705fe7b129e69ac3ee9df7360983d1ab2432f57 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 7 Oct 2010 15:12:06 -0700 Subject: [PATCH 81/88] Added tag jdk7-b113 for changeset 4fb06c9f1ce0 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index cc365510f54..da1bccd72ad 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -122,3 +122,4 @@ cc4bb3022b3144dc5db0805b9ef6c7eff2aa3b81 jdk7-b109 2f25f2b8de2700a1822463b1bd3d02b5e218018f jdk7-b110 07b042e13dde4f3479ba9ec55120fcd5e8623323 jdk7-b111 5511edd5d719f3fc9fdd04879482026a3d2c8652 jdk7-b112 +beef35b96b81129c375d572357fb9548d9020db1 jdk7-b113 From a6e5f5eb910d63c128ffbe953bbcd4094fafb4b5 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 7 Oct 2010 15:12:11 -0700 Subject: [PATCH 82/88] Added tag jdk7-b113 for changeset 039713686e1c --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 443af650ea0..e3050dd6df5 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -87,3 +87,4 @@ d42c4acb6424a094bdafe2ad9c8c1c7ca7fb7b7e jdk7-b104 d422dbdd09766269344b796b3a46a5b3f74557e1 jdk7-b110 8106c747067c905d814a737a57fea0e29057b33f jdk7-b111 1b05254242881527b4d5d711295c0fe708c8823a jdk7-b112 +bc0c84ce54c34d3e8b0604b94da0d7c75c26755e jdk7-b113 From ea504457e0bcc5d2dd073ca6b291b89e7c016574 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 7 Oct 2010 15:12:12 -0700 Subject: [PATCH 83/88] Added tag jdk7-b113 for changeset 9d2d843d318f --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 7befc114031..12e62c797d0 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -87,3 +87,4 @@ b1ca39340238a239ba6d8489ad5315215e1366ca jdk7-b108 95ecac35fb11530752bd0404c9bf02bcfb30990e jdk7-b110 2575ebca96c7fb1b78f6ae025a97321210aba309 jdk7-b111 8e0f0054817f0f73fb33e80fb1333fb45b1d513d jdk7-b112 +d35c94fd22362f478f75b4bfcd2bef6a83cb9b3f jdk7-b113 From 545a4719069cc59e40c0ca4a3e77dec47d7cdae3 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 7 Oct 2010 15:12:19 -0700 Subject: [PATCH 84/88] Added tag jdk7-b113 for changeset 2347b7452dcd --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index f5bbc9b6da0..b49ddeec2f9 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -87,3 +87,4 @@ ab0d3f54a63f2aadfcdd2e14b81f79362ce454e2 jdk7-b109 176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111 b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112 +61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113 From 85df6f646d64d888d8f88cd5081fb69d662aa58f Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 7 Oct 2010 15:12:31 -0700 Subject: [PATCH 85/88] Added tag jdk7-b113 for changeset edcbadb1c4b3 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 49a9474e349..0d6cdae403a 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -87,3 +87,4 @@ a408ebb8b3d427dbb3d8ce153dfaeb060564a0a4 jdk7-b108 32da0f38d2fe96c558492b8707b40da24643d41e jdk7-b110 8bec624274ef8535720cff553374347c2f4f5fb2 jdk7-b111 fd2579b80b83bf5d4289426016c7d29174ba5dd9 jdk7-b112 +6dbd2d869b0573fa5b799a23cccff47d20c12696 jdk7-b113 From 2d526410d44047e2a5161f6b0df9175af45af013 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Fri, 8 Oct 2010 21:33:28 -0700 Subject: [PATCH 86/88] 6990846: Demo: NIO.2 filesystem provider for zip/jar archives The first drop of the zip filesystem provider, as a separate demo Reviewed-by: alanb --- jdk/make/mkdemo/Makefile | 2 +- jdk/make/mkdemo/nio/Makefile | 39 + jdk/make/mkdemo/nio/zipfs/Makefile | 44 + jdk/src/share/demo/nio/zipfs/Demo.java | 664 +++++ .../java.nio.file.spi.FileSystemProvider | 3 + jdk/src/share/demo/nio/zipfs/README.txt | 29 + .../sun/nio/zipfs/JarFileSystemProvider.java | 71 + .../nio/zipfs/com/sun/nio/zipfs/ZipCoder.java | 160 ++ .../zipfs/com/sun/nio/zipfs/ZipConstants.java | 261 ++ .../com/sun/nio/zipfs/ZipDirectoryStream.java | 109 + .../sun/nio/zipfs/ZipFileAttributeView.java | 185 ++ .../com/sun/nio/zipfs/ZipFileAttributes.java | 156 ++ .../zipfs/com/sun/nio/zipfs/ZipFileStore.java | 157 ++ .../com/sun/nio/zipfs/ZipFileSystem.java | 2257 +++++++++++++++++ .../sun/nio/zipfs/ZipFileSystemProvider.java | 152 ++ .../nio/zipfs/com/sun/nio/zipfs/ZipInfo.java | 132 + .../nio/zipfs/com/sun/nio/zipfs/ZipPath.java | 964 +++++++ .../nio/zipfs/com/sun/nio/zipfs/ZipUtils.java | 289 +++ jdk/test/demo/zipfs/Basic.java | 159 ++ jdk/test/demo/zipfs/PathOps.java | 416 +++ jdk/test/demo/zipfs/ZipFSTester.java | 633 +++++ jdk/test/demo/zipfs/basic.sh | 73 + 22 files changed, 6954 insertions(+), 1 deletion(-) create mode 100644 jdk/make/mkdemo/nio/Makefile create mode 100644 jdk/make/mkdemo/nio/zipfs/Makefile create mode 100644 jdk/src/share/demo/nio/zipfs/Demo.java create mode 100644 jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider create mode 100644 jdk/src/share/demo/nio/zipfs/README.txt create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java create mode 100644 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java create mode 100644 jdk/test/demo/zipfs/Basic.java create mode 100644 jdk/test/demo/zipfs/PathOps.java create mode 100644 jdk/test/demo/zipfs/ZipFSTester.java create mode 100644 jdk/test/demo/zipfs/basic.sh diff --git a/jdk/make/mkdemo/Makefile b/jdk/make/mkdemo/Makefile index cda377f83f2..5a54d2795cd 100644 --- a/jdk/make/mkdemo/Makefile +++ b/jdk/make/mkdemo/Makefile @@ -31,7 +31,7 @@ BUILDDIR = .. PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = jni +SUBDIRS = jni nio SUBDIRS_desktop = applets jfc SUBDIRS_management = management SUBDIRS_misc = scripting diff --git a/jdk/make/mkdemo/nio/Makefile b/jdk/make/mkdemo/nio/Makefile new file mode 100644 index 00000000000..26dc772b213 --- /dev/null +++ b/jdk/make/mkdemo/nio/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# Makefile for building the jfc demos +# + +BUILDDIR = ../.. +PRODUCT = demos +include $(BUILDDIR)/common/Defs.gmk + +SUBDIRS = zipfs +include $(BUILDDIR)/common/Subdirs.gmk + +all build clean clobber:: + $(SUBDIRS-loop) + diff --git a/jdk/make/mkdemo/nio/zipfs/Makefile b/jdk/make/mkdemo/nio/zipfs/Makefile new file mode 100644 index 00000000000..16e71a9ba45 --- /dev/null +++ b/jdk/make/mkdemo/nio/zipfs/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# Makefile to build the ZipFileSystem demo. +# + +BUILDDIR = ../../.. +PRODUCT = demo/zipfs +DEMONAME = zipfs +include $(BUILDDIR)/common/Defs.gmk + +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME) +DEMO_TOPFILES = ./README.txt +DEMO_SRCDIR = $(DEMO_ROOT) +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME) + +# +# Demo jar building rules. +# +include $(BUILDDIR)/common/Demo.gmk + diff --git a/jdk/src/share/demo/nio/zipfs/Demo.java b/jdk/src/share/demo/nio/zipfs/Demo.java new file mode 100644 index 00000000000..3666dfd70de --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/Demo.java @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * ZipFileSystem usage demo + * + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...] + * + * To deploy the provider, either copy the zipfs.jar into JDK/JRE + * extensions directory or add + * /demo/nio/ZipFileSystem/zipfs.jar + * into your class path as showed above. + * + * @author Xueming Shen + */ + +public class Demo { + + static enum Action { + rename, // + // rename entry src to dst inside zipfile + + movein, // + // move an external src file into zipfile + // as entry dst + + moveout, // + // move a zipfile entry src out to dst + + copy, // + // copy entry src to dst inside zipfile + + copyin, // + // copy an external src file into zipfile + // as entry dst + + copyout, // + // copy zipfile entry src" out to file dst + + zzmove, // + // move entry path/dir from zfsrc to zfdst + + zzcopy, // + // copy path from zipfile zfsrc to zipfile + // zfdst + + attrs, // + // printout the attributes of entry path + + attrsspace, // + // printout the storespace attrs of entry path + + setmtime, // + // set the lastModifiedTime of entry path + + lsdir, // + // list dir's direct child files/dirs + + mkdir, // + + mkdirs, // + + rmdirs, // + + list, // + // recursively list all entries of dir + // via DirectoryStream + + tlist, // + // list with buildDirTree=true + + vlist, // + // recursively verbose list all entries of + // dir via DirectoryStream + + walk, // + // recursively walk all entries of dir + // via Files.walkFileTree + + twalk, // + // walk with buildDirTree=true + + extract, // + + update, // + + delete, // + + add, // + + create, // + // create a new zipfile if it doesn't exit + // and then add the file(s) into it. + + attrs2, // + // test different ways to print attrs + } + + public static void main(String[] args) throws Throwable { + + Action action = Action.valueOf(args[0]);; + Map env = env = new HashMap(); + if (action == Action.create) + env.put("createNew", true); + if (action == Action.tlist || action == Action.twalk) + env.put("buildDirTree", true); + + FileSystem fs = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)), + env, + null); + try { + FileSystem fs2; + Path path, src, dst; + boolean isRename = false; + switch (action) { + case rename: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + src.moveTo(dst); + break; + case moveout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + src.moveTo(dst); + break; + case movein: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + src.moveTo(dst); + break; + case copy: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + src.copyTo(dst); + break; + case copyout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + src.copyTo(dst); + break; + case copyin: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + src.copyTo(dst); + break; + case zzmove: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + env, + null); + //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3])); + z2zmove(fs, fs2, args[3]); + fs2.close(); + break; + case zzcopy: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + env, + null); + //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3])); + z2zcopy(fs, fs2, args[3]); + fs2.close(); + break; + case attrs: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + } + break; + case setmtime: + DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); + Date newDatetime = df.parse(args[2]); + for (int i = 3; i < args.length; i++) { + path = fs.getPath(args[i]); + path.setAttribute("lastModifiedTime", + FileTime.fromMillis(newDatetime.getTime())); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + } + break; + case attrsspace: + path = fs.getPath("/"); + FileStore fstore = path.getFileStore(); + //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class) + // .readAttributes()); + // or + System.out.printf("filestore[%s]%n", fstore.name()); + System.out.printf(" totalSpace: %d%n", + (Long)fstore.getAttribute("space:totalSpace")); + System.out.printf(" usableSpace: %d%n", + (Long)fstore.getAttribute("space:usableSpace")); + System.out.printf(" unallocSpace: %d%n", + (Long)fstore.getAttribute("space:unallocatedSpace")); + break; + case list: + case tlist: + if (args.length < 3) + list(fs.getPath("/"), false); + else + list(fs.getPath(args[2]), false); + break; + case vlist: + if (args.length < 3) + list(fs.getPath("/"), true); + else + list(fs.getPath(args[2]), true); + break; + case twalk: + case walk: + walk(fs.getPath((args.length > 2)? args[2] : "/")); + break; + case extract: + if (args.length == 2) { + extract(fs, "/"); + } else { + for (int i = 2; i < args.length; i++) { + extract(fs, args[i]); + } + } + break; + case delete: + for (int i = 2; i < args.length; i++) + fs.getPath(args[i]).delete(); + break; + case create: + case add: + case update: + for (int i = 2; i < args.length; i++) { + update(fs, args[i]); + } + break; + case lsdir: + path = fs.getPath(args[2]); + final String fStr = (args.length > 3)?args[3]:""; + DirectoryStream ds = path.newDirectoryStream( + new DirectoryStream.Filter() { + public boolean accept(Path path) { + return path.toString().contains(fStr); + } + }); + for (Path p : ds) + System.out.println(p); + break; + case mkdir: + fs.getPath(args[2]).createDirectory(); + break; + case mkdirs: + mkdirs(fs.getPath(args[2])); + break; + case attrs2: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println("-------(1)---------"); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + System.out.println("-------(2)---------"); + Map map = path.readAttributes("zip:*"); + for (Map.Entry e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + System.out.println("-------(3)---------"); + map = path.readAttributes("size,lastModifiedTime,isDirectory"); + for (Map.Entry e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + } + break; + } + } catch (Exception x) { + x.printStackTrace(); + } finally { + if (fs != null) + fs.close(); + } + } + + private static byte[] getBytes(String name) { + return name.getBytes(); + } + + private static String getString(byte[] name) { + return new String(name); + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void update(FileSystem fs, String path) throws Throwable{ + Path src = FileSystems.getDefault().getPath(path); + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) { + DirectoryStream ds = src.newDirectoryStream(); + for (Path child : ds) + update(fs, child.toString()); + ds.close(); + } else { + Path dst = fs.getPath(path); + Path parent = dst.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + src.copyTo(dst, REPLACE_EXISTING); + } + } + + private static void extract(FileSystem fs, String path) throws Throwable{ + Path src = fs.getPath(path); + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) { + DirectoryStream ds = src.newDirectoryStream(); + for (Path child : ds) + extract(fs, child.toString()); + ds.close(); + } else { + if (path.startsWith("/")) + path = path.substring(1); + Path dst = FileSystems.getDefault().getPath(path); + Path parent = dst.getParent(); + if (parent.notExists()) + mkdirs(parent); + src.copyTo(dst, REPLACE_EXISTING); + } + } + + // use DirectoryStream + private static void z2zcopy(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName()); + } + ds.close(); + } else { + //System.out.println("copying..." + path); + srcPath.copyTo(dstPath); + } + } + + // use TreeWalk to move + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + final Path srcPath = src.getPath(path).toAbsolutePath(); + final Path dstPath = dst.getPath(path).toAbsolutePath(); + + Files.walkFileTree(srcPath, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(file); + dst = dstPath.resolve(dst); + try { + Path parent = dstPath.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + file.moveTo(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(dir); + dst = dstPath.resolve(dst); + try { + + if (dst.notExists()) + mkdirs(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + try { + dir.delete(); + } catch (IOException x) { + //x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + }); + + } + + private static void mkdirs(Path path) throws IOException { + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (parent.notExists()) + mkdirs(parent); + } + path.createDirectory(); + } + + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + path.delete(); + path = path.getParent(); + } + } + + private static void list(Path path, boolean verbose ) throws IOException { + if (verbose) + System.out.println(Attributes.readBasicFileAttributes(path).toString()); + else + System.out.printf(" %s%n", path.toString()); + if (path.notExists()) + return; + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream ds = path.newDirectoryStream(); + for (Path child : ds) + list(child, verbose); + ds.close(); + } + } + + // check the content of two paths are equal + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + InputStream isSrc = src.newInputStream(); + InputStream isDst = dst.newInputStream(); + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + + try { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } finally { + isSrc.close(); + isDst.close(); + } + + // channels + SeekableByteChannel chSrc = src.newByteChannel(); + SeekableByteChannel chDst = dst.newByteChannel(); + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + try { + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + } catch (IOException x) { + x.printStackTrace(); + } finally { + chSrc.close(); + chDst.close(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + FileChannel srcFc = src.getFileSystem() + .provider() + .newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem() + .provider() + .newFileChannel(dst, openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } finally { + srcFc.close(); + dstFc.close(); + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + SeekableByteChannel srcCh = src.newByteChannel(read); + SeekableByteChannel dstCh = dst.newByteChannel(openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + } finally { + srcCh.close(); + dstCh.close(); + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + InputStream isSrc = src.newInputStream(); + OutputStream osDst = dst.newOutputStream(); + byte[] buf = new byte[8192]; + try { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } finally { + isSrc.close(); + osDst.close(); + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider new file mode 100644 index 00000000000..ace131aa0fd --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider @@ -0,0 +1,3 @@ +com.sun.nio.zipfs.ZipFileSystemProvider +com.sun.nio.zipfs.JarFileSystemProvider + diff --git a/jdk/src/share/demo/nio/zipfs/README.txt b/jdk/src/share/demo/nio/zipfs/README.txt new file mode 100644 index 00000000000..227a67e270e --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/README.txt @@ -0,0 +1,29 @@ +ZipFileSystem is a file system provider that treats the contents of a zip or +JAR file as a java.nio.file.FileSystem. + +To deploy the provider you must copy zipfs.jar into your extensions +directory or else add /demo/nio/ZipFileSystem/zipfs.jar +to your class path. + +The factory methods defined by the java.nio.file.FileSystems class can be +used to create a FileSystem, eg: + + // use file type detection + Map env = Collections.emptyMap(); + Path jarfile = Path.get("foo.jar"); + FileSystem fs = FileSystems.newFileSystem(jarfile, env); + +-or + + // locate file system by URI + Map env = Collections.emptyMap(); + URI uri = URI.create("zip:///mydir/foo.jar"); + FileSystem fs = FileSystems.newFileSystem(uri, env); + +Once a FileSystem is created then classes in the java.nio.file package +can be used to access files in the zip/JAR file, eg: + + Path mf = fs.getPath("/META-INF/MANIFEST.MF"); + InputStream in = mf.newInputStream(); + + diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java new file mode 100644 index 00000000000..2fc9c83ef14 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java @@ -0,0 +1,71 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Sun Microsystems nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.sun.nio.zipfs; + +import java.nio.file.*; +import java.nio.file.spi.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; + +import java.net.URI; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.channels.FileChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class JarFileSystemProvider extends ZipFileSystemProvider +{ + + @Override + public String getScheme() { + return "jar"; + } + + @Override + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + String uristr = uri.toString(); + int end = uristr.indexOf("!/"); + uristr = uristr.substring(4, (end == -1) ? uristr.length() : end); + uri = new URI(uristr); + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) + .toAbsolutePath(); + } catch (URISyntaxException e) { + throw new AssertionError(e); //never thrown + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java new file mode 100644 index 00000000000..92c5535ab19 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.util.Arrays; + +/** + * Utility class for zipfile name and comment decoding and encoding + * + * @author Xueming Shen + */ + +final class ZipCoder { + + String toString(byte[] ba, int length) { + CharsetDecoder cd = decoder().reset(); + int len = (int)(length * cd.maxCharsPerByte()); + char[] ca = new char[len]; + if (len == 0) + return new String(ca); + ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = cd.decode(bb, cb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = cd.flush(cb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + return new String(ca, 0, cb.position()); + } + + String toString(byte[] ba) { + return toString(ba, ba.length); + } + + byte[] getBytes(String s) { + CharsetEncoder ce = encoder().reset(); + char[] ca = s.toCharArray(); + int len = (int)(ca.length * ce.maxBytesPerChar()); + byte[] ba = new byte[len]; + if (len == 0) + return ba; + ByteBuffer bb = ByteBuffer.wrap(ba); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = ce.encode(cb, bb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = ce.flush(bb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + if (bb.position() == ba.length) // defensive copy? + return ba; + else + return Arrays.copyOf(ba, bb.position()); + } + + // assume invoked only if "this" is not utf8 + byte[] getBytesUTF8(String s) { + if (isutf8) + return getBytes(s); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.getBytes(s); + } + + String toStringUTF8(byte[] ba, int len) { + if (isutf8) + return toString(ba, len); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.toString(ba, len); + } + + boolean isUTF8() { + return isutf8; + } + + private Charset cs; + private boolean isutf8; + private ZipCoder utf8; + + private ZipCoder(Charset cs) { + this.cs = cs; + this.isutf8 = cs.name().equals("UTF-8"); + } + + static ZipCoder get(Charset charset) { + return new ZipCoder(charset); + } + + static ZipCoder get(String csn) { + try { + return new ZipCoder(Charset.forName(csn)); + } catch (Throwable t) { + t.printStackTrace(); + } + return new ZipCoder(Charset.defaultCharset()); + } + + private final ThreadLocal decTL = new ThreadLocal<>(); + private final ThreadLocal encTL = new ThreadLocal<>(); + + private CharsetDecoder decoder() { + CharsetDecoder dec = decTL.get(); + if (dec == null) { + dec = cs.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + decTL.set(dec); + } + return dec; + } + + private CharsetEncoder encoder() { + CharsetEncoder enc = encTL.get(); + if (enc == null) { + enc = cs.newEncoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + encTL.set(enc); + } + return enc; + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java new file mode 100644 index 00000000000..aa7073ac15e --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.ByteBuffer; + +/** + * + * @author Xueming Shen + */ + +class ZipConstants { + /* + * Compression methods + */ + static final int METHOD_STORED = 0; + static final int METHOD_DEFLATED = 8; + static final int METHOD_DEFLATED64 = 9; + static final int METHOD_BZIP2 = 12; + static final int METHOD_LZMA = 14; + static final int METHOD_LZ77 = 19; + + /* + * General purpose big flag + */ + static final int FLAG_ENCRYPTED = 0x01; + static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd + static final int FLAG_EFS = 0x800; // If this bit is set the filename and + // comment fields for this file must be + // encoded using UTF-8. + /* + * Header signatures + */ + static long LOCSIG = 0x04034b50L; // "PK\003\004" + static long EXTSIG = 0x08074b50L; // "PK\007\008" + static long CENSIG = 0x02014b50L; // "PK\001\002" + static long ENDSIG = 0x06054b50L; // "PK\005\006" + + /* + * Header sizes in bytes (including signatures) + */ + static final int LOCHDR = 30; // LOC header size + static final int EXTHDR = 16; // EXT header size + static final int CENHDR = 46; // CEN header size + static final int ENDHDR = 22; // END header size + + /* + * Local file (LOC) header field offsets + */ + static final int LOCVER = 4; // version needed to extract + static final int LOCFLG = 6; // general purpose bit flag + static final int LOCHOW = 8; // compression method + static final int LOCTIM = 10; // modification time + static final int LOCCRC = 14; // uncompressed file crc-32 value + static final int LOCSIZ = 18; // compressed size + static final int LOCLEN = 22; // uncompressed size + static final int LOCNAM = 26; // filename length + static final int LOCEXT = 28; // extra field length + + /* + * Extra local (EXT) header field offsets + */ + static final int EXTCRC = 4; // uncompressed file crc-32 value + static final int EXTSIZ = 8; // compressed size + static final int EXTLEN = 12; // uncompressed size + + /* + * Central directory (CEN) header field offsets + */ + static final int CENVEM = 4; // version made by + static final int CENVER = 6; // version needed to extract + static final int CENFLG = 8; // encrypt, decrypt flags + static final int CENHOW = 10; // compression method + static final int CENTIM = 12; // modification time + static final int CENCRC = 16; // uncompressed file crc-32 value + static final int CENSIZ = 20; // compressed size + static final int CENLEN = 24; // uncompressed size + static final int CENNAM = 28; // filename length + static final int CENEXT = 30; // extra field length + static final int CENCOM = 32; // comment length + static final int CENDSK = 34; // disk number start + static final int CENATT = 36; // internal file attributes + static final int CENATX = 38; // external file attributes + static final int CENOFF = 42; // LOC header offset + + /* + * End of central directory (END) header field offsets + */ + static final int ENDSUB = 8; // number of entries on this disk + static final int ENDTOT = 10; // total number of entries + static final int ENDSIZ = 12; // central directory size in bytes + static final int ENDOFF = 16; // offset of first CEN header + static final int ENDCOM = 20; // zip file comment length + + /* + * ZIP64 constants + */ + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size + static final int ZIP64_EXTHDR = 24; // EXT header size + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID + + static final int ZIP64_MINVAL32 = 0xFFFF; + static final long ZIP64_MINVAL = 0xFFFFFFFFL; + + /* + * Zip64 End of central directory (END) header field offsets + */ + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir + static final int ZIP64_ENDVEM = 12; // version made by + static final int ZIP64_ENDVER = 14; // version needed to extract + static final int ZIP64_ENDNMD = 16; // number of this disk + static final int ZIP64_ENDDSK = 20; // disk number of start + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk + static final int ZIP64_ENDTOT = 32; // total number of entries + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes + static final int ZIP64_ENDOFF = 48; // offset of first CEN header + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector + + /* + * Zip64 End of central directory locator field offsets + */ + static final int ZIP64_LOCDSK = 4; // disk number start + static final int ZIP64_LOCOFF = 8; // offset of zip64 end + static final int ZIP64_LOCTOT = 16; // total number of disks + + /* + * Zip64 Extra local (EXT) header field offsets + */ + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte + + /* + * Extra field header ID + */ + static final int EXTID_ZIP64 = 0x0001; // ZIP64 + static final int EXTID_NTFS = 0x000a; // NTFS + static final int EXTID_UNIX = 0x000d; // UNIX + + + /* + * fields access methods + */ + /////////////////////////////////////////////////////// + static final int CH(byte[] b, int n) { + return b[n] & 0xff; + } + + static final int SH(byte[] b, int n) { + return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8); + } + + static final long LG(byte[] b, int n) { + return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL; + } + + static final long LL(byte[] b, int n) { + return (LG(b, n)) | (LG(b, n + 4) << 32); + } + + static final long GETSIG(byte[] b) { + return LG(b, 0); + } + + // local file (LOC) header fields + static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature + static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract + static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags + static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method + static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time + static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data + static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size + static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size + static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length + static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length + + // extra local (EXT) header fields + static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data + static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size + static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size + + // end of central directory header (END) fields + static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk + static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries + static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size + static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset + static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment + static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);} + + // zip64 end of central directory recoder fields + static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk + static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries + static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size + static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset + static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset + + ////////////////////////////////////////// + static final int CH(ByteBuffer b, int pos) { + return b.get(pos) & 0xff; + } + static final int SH(ByteBuffer b, int pos) { + return b.getShort(pos) & 0xffff; + } + static final long LG(ByteBuffer b, int pos) { + return b.getInt(pos) & 0xffffffffL; + } + + // central directory header (END) fields + static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); } + static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); } + static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); } + static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); } + static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);} + static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);} + static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);} + static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);} + static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);} + static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);} + static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);} + static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);} + static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);} + static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);} + static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);} + static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);} + + /* The END header is followed by a variable length comment of size < 64k. */ + static final long END_MAXLEN = 0xFFFF + ENDHDR; + static final int READBLOCKSZ = 128; +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java new file mode 100644 index 00000000000..3052b34e59a --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.file.DirectoryStream; +import java.nio.file.ClosedDirectoryStreamException; +import java.nio.file.NotDirectoryException; +import java.nio.file.Path; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.io.IOException; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipDirectoryStream implements DirectoryStream { + + private final ZipFileSystem zipfs; + private final byte[] path; + private final DirectoryStream.Filter filter; + private volatile boolean isClosed; + private volatile Iterator itr; + + ZipDirectoryStream(ZipPath zipPath, + DirectoryStream.Filter filter) + throws IOException + { + this.zipfs = zipPath.getFileSystem(); + this.path = zipPath.getResolvedPath(); + this.filter = filter; + // sanity check + if (!zipfs.isDirectory(path)) + throw new NotDirectoryException(zipPath.toString()); + } + + @Override + public synchronized Iterator iterator() { + if (isClosed) + throw new ClosedDirectoryStreamException(); + if (itr != null) + throw new IllegalStateException("Iterator has already been returned"); + + try { + itr = zipfs.iteratorOf(path, filter); + } catch (IOException e) { + throw new IllegalStateException(e); + } + return new Iterator() { + private Path next; + @Override + public boolean hasNext() { + if (isClosed) + return false; + return itr.hasNext(); + } + + @Override + public synchronized Path next() { + if (isClosed) + throw new NoSuchElementException(); + return itr.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public synchronized void close() throws IOException { + isClosed = true; + } + + +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java new file mode 100644 index 00000000000..d4a9a67c9fc --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +package com.sun.nio.zipfs; + +import java.nio.file.ReadOnlyFileSystemException; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileTime; +import java.io.IOException; +import java.util.LinkedHashMap; + +/* + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileAttributeView implements BasicFileAttributeView +{ + private static enum AttrID { + size, + creationTime, + lastAccessTime, + lastModifiedTime, + isDirectory, + isRegularFile, + isSymbolicLink, + isOther, + fileKey, + compressedSize, + crc, + method + }; + + private final ZipPath path; + private final boolean isZipView; + + private ZipFileAttributeView(ZipPath path, boolean isZipView) { + this.path = path; + this.isZipView = isZipView; + } + + static V get(ZipPath path, Class type) { + if (type == null) + throw new NullPointerException(); + if (type == BasicFileAttributeView.class) + return (V)new ZipFileAttributeView(path, false); + if (type == ZipFileAttributeView.class) + return (V)new ZipFileAttributeView(path, true); + return null; + } + + static ZipFileAttributeView get(ZipPath path, String type) { + if (type == null) + throw new NullPointerException(); + if (type.equals("basic")) + return new ZipFileAttributeView(path, false); + if (type.equals("zip")) + return new ZipFileAttributeView(path, true); + return null; + } + + @Override + public String name() { + return isZipView ? "zip" : "basic"; + } + + public ZipFileAttributes readAttributes() throws IOException + { + return path.getAttributes(); + } + + @Override + public void setTimes(FileTime lastModifiedTime, + FileTime lastAccessTime, + FileTime createTime) + throws IOException + { + path.setTimes(lastModifiedTime, lastAccessTime, createTime); + } + + void setAttribute(String attribute, Object value) + throws IOException + { + try { + if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime) + setTimes ((FileTime)value, null, null); + return; + } catch (IllegalArgumentException x) {} + throw new UnsupportedOperationException("'" + attribute + + "' is unknown or read-only attribute"); + } + + public Object getAttribute(String attribute, boolean domap) + throws IOException + { + ZipFileAttributes zfas = readAttributes(); + if (!domap) { + try { + return attribute(AttrID.valueOf(attribute), zfas); + } catch (IllegalArgumentException x) {} + return null; + } + LinkedHashMap map = new LinkedHashMap<>(); + if ("*".equals(attribute)) { + for (AttrID id : AttrID.values()) { + try { + map.put(id.name(), attribute(id, zfas)); + } catch (IllegalArgumentException x) {} + } + } else { + String[] as = attribute.split(","); + for (String a : as) { + try { + map.put(a, attribute(AttrID.valueOf(a), zfas)); + } catch (IllegalArgumentException x) {} + } + } + return map; + } + + Object attribute(AttrID id, ZipFileAttributes zfas) { + switch (id) { + case size: + return zfas.size(); + case creationTime: + return zfas.creationTime(); + case lastAccessTime: + return zfas.lastAccessTime(); + case lastModifiedTime: + return zfas.lastModifiedTime(); + case isDirectory: + return zfas.isDirectory(); + case isRegularFile: + return zfas.isRegularFile(); + case isSymbolicLink: + return zfas.isSymbolicLink(); + case isOther: + return zfas.isOther(); + case fileKey: + return zfas.fileKey(); + case compressedSize: + if (isZipView) + return zfas.compressedSize(); + break; + case crc: + if (isZipView) + return zfas.crc(); + break; + case method: + if (isZipView) + return zfas.method(); + break; + } + return null; + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java new file mode 100644 index 00000000000..157f9eb163a --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +package com.sun.nio.zipfs; + +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.Arrays; +import java.util.Formatter; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal + */ + +public class ZipFileAttributes implements BasicFileAttributes + +{ + private final ZipFileSystem.Entry e; + + ZipFileAttributes(ZipFileSystem.Entry e) { + this.e = e; + } + + ///////// basic attributes /////////// + @Override + public FileTime creationTime() { + if (e.ctime != -1) + return FileTime.fromMillis(dosToJavaTime(e.ctime)); + return null; + } + + @Override + public boolean isDirectory() { + return e.isDir(); + } + + @Override + public boolean isOther() { + return false; + } + + @Override + public boolean isRegularFile() { + return !e.isDir(); + } + + @Override + public FileTime lastAccessTime() { + if (e.atime != -1) + return FileTime.fromMillis(dosToJavaTime(e.atime)); + return null; + } + + @Override + public FileTime lastModifiedTime() { + return FileTime.fromMillis(dosToJavaTime(e.mtime)); + } + + @Override + public long size() { + return e.size; + } + + @Override + public boolean isSymbolicLink() { + return false; + } + + @Override + public Object fileKey() { + return null; + } + + ///////// zip entry attributes /////////// + public byte[] name() { + return Arrays.copyOf(e.name, e.name.length); + } + + public long compressedSize() { + return e.csize; + } + + public long crc() { + return e.crc; + } + + public int method() { + return e.method; + } + + public byte[] extra() { + if (e.extra != null) + return Arrays.copyOf(e.extra, e.extra.length); + return null; + } + + public byte[] comment() { + if (e.comment != null) + return Arrays.copyOf(e.comment, e.comment.length); + return null; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + Formatter fm = new Formatter(sb); + fm.format("[/%s]%n", new String(e.name)); // TBD encoding + fm.format(" creationTime : %s%n", creationTime()); + if (lastAccessTime() != null) + fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis()); + else + fm.format(" lastAccessTime : null%n"); + fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis()); + fm.format(" isRegularFile : %b%n", isRegularFile()); + fm.format(" isDirectory : %b%n", isDirectory()); + fm.format(" isSymbolicLink : %b%n", isSymbolicLink()); + fm.format(" isOther : %b%n", isOther()); + fm.format(" fileKey : %s%n", fileKey()); + fm.format(" size : %d%n", size()); + fm.format(" compressedSize : %d%n", compressedSize()); + fm.format(" crc : %x%n", crc()); + fm.format(" method : %d%n", method()); + fm.close(); + return sb.toString(); + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java new file mode 100644 index 00000000000..681509719e7 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.IOException; +import java.nio.file.FileStore; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileStoreAttributeView; +import java.nio.file.attribute.FileStoreSpaceAttributeView; +import java.nio.file.attribute.FileStoreSpaceAttributes; +import java.nio.file.attribute.Attributes; +import java.nio.file.attribute.BasicFileAttributeView; +import java.util.Formatter; + +/* + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileStore extends FileStore { + + private final ZipFileSystem zfs; + + ZipFileStore(ZipPath zpath) { + this.zfs = (ZipFileSystem)zpath.getFileSystem(); + } + + @Override + public String name() { + return zfs.toString() + "/"; + } + + @Override + public String type() { + return "zipfs"; + } + + @Override + public boolean isReadOnly() { + return zfs.isReadOnly(); + } + + @Override + public boolean supportsFileAttributeView(Class type) { + return (type == BasicFileAttributeView.class || + type == ZipFileAttributeView.class); + } + + @Override + public boolean supportsFileAttributeView(String name) { + return name.equals("basic") || name.equals("zip"); + } + + @Override + @SuppressWarnings("unchecked") + public V getFileStoreAttributeView(Class type) { + if (type == null) + throw new NullPointerException(); + if (type == FileStoreSpaceAttributeView.class) + return (V) new ZipFileStoreAttributeView(this); + return null; + } + + @Override + public Object getAttribute(String attribute) throws IOException { + if (attribute.equals("space:totalSpace")) + return new ZipFileStoreAttributeView(this).readAttributes().totalSpace(); + if (attribute.equals("space:usableSpace")) + return new ZipFileStoreAttributeView(this).readAttributes().usableSpace(); + if (attribute.equals("space:unallocatedSpace")) + return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace(); + throw new UnsupportedOperationException("does not support the given attribute"); + } + + private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView { + + private final ZipFileStore fileStore; + + public ZipFileStoreAttributeView(ZipFileStore fileStore) { + this.fileStore = fileStore; + } + + @Override + public String name() { + return "space"; + } + + @Override + public FileStoreSpaceAttributes readAttributes() throws IOException { + final String file = fileStore.name(); + Path path = FileSystems.getDefault().getPath(file); + final long size = Attributes.readBasicFileAttributes(path).size(); + final FileStore fstore = path.getFileStore(); + final FileStoreSpaceAttributes fstoreAttrs = + Attributes.readFileStoreSpaceAttributes(fstore); + return new FileStoreSpaceAttributes() { + public long totalSpace() { + return size; + } + + public long usableSpace() { + if (!fstore.isReadOnly()) + return fstoreAttrs.usableSpace(); + return 0; + } + + public long unallocatedSpace() { + if (!fstore.isReadOnly()) + return fstoreAttrs.unallocatedSpace(); + return 0; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + Formatter fm = new Formatter(sb); + fm.format("FileStoreSpaceAttributes[%s]%n", file); + fm.format(" totalSpace: %d%n", totalSpace()); + fm.format(" usableSpace: %d%n", usableSpace()); + fm.format(" unallocSpace: %d%n", unallocatedSpace()); + fm.close(); + return sb.toString(); + } + }; + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java new file mode 100644 index 00000000000..152ca957c1d --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java @@ -0,0 +1,2257 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.*; +import java.net.URI; +import java.util.*; +import java.util.regex.Pattern; +import java.util.zip.CRC32; +import java.util.zip.Inflater; +import java.util.zip.Deflater; +import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.ZipException; +import java.util.zip.ZipError; +import static java.lang.Boolean.*; +import static com.sun.nio.zipfs.ZipConstants.*; +import static com.sun.nio.zipfs.ZipUtils.*; +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/** + * A FileSystem built on a zip file + * + * @author Xueming Shen + */ + +public class ZipFileSystem extends FileSystem { + + private final ZipFileSystemProvider provider; + private final ZipPath defaultdir; + private boolean readOnly = false; + private final Path zfpath; + private final ZipCoder zc; + + private final Object lock = new Object(); + + // configurable by env map + private final String defaultDir; // default dir for the file system + private final String nameEncoding; // default encoding for name/comment + private final boolean buildDirTree; // build a dir tree for directoryStream ops + private final boolean useTempFile; // use a temp file for newOS, default + // is to use BAOS for better performance + private final boolean createNew; // create a new zip if not exists + + ZipFileSystem(ZipFileSystemProvider provider, + Path zfpath, + Map env) + throws IOException + { + // configurable env setup + this.buildDirTree = TRUE.equals(env.get("buildDirTree")); + this.useTempFile = TRUE.equals(env.get("useTempFile")); + this.createNew = TRUE.equals(env.get("createNew")); + this.nameEncoding = env.containsKey("nameEncoding") ? + (String)env.get("nameEncoding") : "UTF-8"; + this.defaultDir = env.containsKey("default.dir") ? + (String)env.get("default.dir") : "/"; + if (this.defaultDir.charAt(0) != '/') + throw new IllegalArgumentException("default dir should be absolute"); + + this.provider = provider; + this.zfpath = zfpath; + if (zfpath.notExists()) { + if (createNew) { + OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE); + new END().write(os, 0); + os.close(); + } else { + throw new FileSystemNotFoundException(zfpath.toString()); + } + } + zfpath.checkAccess(AccessMode.READ); // sm and existence check + try { + zfpath.checkAccess(AccessMode.WRITE); + } catch (AccessDeniedException x) { + this.readOnly = true; + } + this.zc = ZipCoder.get(nameEncoding); + this.defaultdir = new ZipPath(this, getBytes(defaultDir)); + initZipFile(); + } + + @Override + public FileSystemProvider provider() { + return provider; + } + + @Override + public String getSeparator() { + return "/"; + } + + @Override + public boolean isOpen() { + return isOpen; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + private void checkWritable() throws IOException { + if (readOnly) + throw new ReadOnlyFileSystemException(); + } + + @Override + public Iterable getRootDirectories() { + ArrayList pathArr = new ArrayList<>(); + pathArr.add(new ZipPath(this, new byte[]{'/'})); + return pathArr; + } + + ZipPath getDefaultDir() { // package private + return defaultdir; + } + + @Override + public ZipPath getPath(String path) { + if (path.length() == 0) + throw new InvalidPathException(path, "path should not be empty"); + return new ZipPath(this, getBytes(path)); + } + + @Override + public UserPrincipalLookupService getUserPrincipalLookupService() { + throw new UnsupportedOperationException(); + } + + @Override + public WatchService newWatchService() { + throw new UnsupportedOperationException(); + } + + FileStore getFileStore(ZipPath path) { + return new ZipFileStore(path); + } + + @Override + public Iterable getFileStores() { + ArrayList list = new ArrayList(1); + list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'}))); + return list; + } + + private static final Set supportedFileAttributeViews = + Collections.unmodifiableSet( + new HashSet(Arrays.asList("basic", "zip"))); + + @Override + public Set supportedFileAttributeViews() { + return supportedFileAttributeViews; + } + + @Override + public String toString() { + return zfpath.toString(); + } + + Path getZipFile() { + return zfpath; + } + + private static final String GLOB_SYNTAX = "glob"; + private static final String REGEX_SYNTAX = "regex"; + + @Override + public PathMatcher getPathMatcher(String syntaxAndInput) { + int pos = syntaxAndInput.indexOf(':'); + if (pos <= 0 || pos == syntaxAndInput.length()) { + throw new IllegalArgumentException(); + } + String syntax = syntaxAndInput.substring(0, pos); + String input = syntaxAndInput.substring(pos + 1); + String expr; + if (syntax.equals(GLOB_SYNTAX)) { + expr = toRegexPattern(input); + } else { + if (syntax.equals(REGEX_SYNTAX)) { + expr = input; + } else { + throw new UnsupportedOperationException("Syntax '" + syntax + + "' not recognized"); + } + } + // return matcher + final Pattern pattern = Pattern.compile(expr); + return new PathMatcher() { + @Override + public boolean matches(Path path) { + return pattern.matcher(path.toString()).matches(); + } + }; + } + + @Override + public void close() throws IOException { + synchronized (lock) { + if (!isOpen) + return; + isOpen = false; + if (!streams.isEmpty()) { + synchronized(streams) { + for (InputStream is: streams) + is.close(); + } + } + sync(); + ch.close(); + } + synchronized (inflaters) { + for (Inflater inf : inflaters) + inf.end(); + } + synchronized (deflaters) { + for (Deflater def : deflaters) + def.end(); + } + for (Path p: tmppaths) { + try { + p.deleteIfExists(); + } catch (IOException x) { + x.printStackTrace(); + } + } + provider.removeFileSystem(zfpath); + } + + ZipFileAttributes[] getAllAttributes() throws IOException { + ensureOpen(); + int n = inodes.size(); + ZipFileAttributes[] zes = new ZipFileAttributes[n]; + Iterator itr = inodes.values().iterator(); + int i = 0; + while(itr.hasNext()) { + zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos)); + } + return zes; + } + + EntryName[] getEntryNames() throws IOException { + ensureOpen(); + return inodes.keySet().toArray(new EntryName[0]); + } + + ZipFileAttributes getFileAttributes(byte[] path) + throws IOException + { + synchronized (lock) { + Entry e = getEntry0(path); + if (e == null) { + if (path.length == 0) { + e = new Entry(new byte[0]); // root + } else if (buildDirTree) { + IndexNode inode = getDirs().get(new EntryName(path)); + if (inode == null) + return null; + e = new Entry(inode.name); + } else { + return null; + } + e.method = METHOD_STORED; // STORED for dir + BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath); + if (bfas.lastModifiedTime() != null) + e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis()); + if (bfas.lastAccessTime() != null) + e.atime = javaToDosTime(bfas.lastAccessTime().toMillis()); + if (bfas.creationTime() != null) + e.ctime = javaToDosTime(bfas.creationTime().toMillis()); + } + return new ZipFileAttributes(e); + } + } + + void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + checkWritable(); + synchronized (lock) { + Entry e = getEntry0(path); // ensureOpen checked + if (e == null) + throw new NoSuchFileException(getString(path)); + if (e.type == Entry.CEN) + e.type = Entry.COPY; // copy e + if (mtime != null) + e.mtime = javaToDosTime(mtime.toMillis()); + if (atime != null) + e.atime = javaToDosTime(atime.toMillis()); + if (ctime != null) + e.ctime = javaToDosTime(ctime.toMillis()); + update(e); + } + } + + boolean exists(byte[] path) + throws IOException + { + return getEntry0(path) != null; + } + + boolean isDirectory(byte[] path) + throws IOException + { + synchronized (lock) { + if (buildDirTree) { + return getDirs().containsKey(new EntryName(path)); + } + Entry e = getEntry0(path); + return (e != null && e.isDir()) || path.length == 0; + } + } + + private ZipPath toZipPath(byte[] path) { + // make it absolute + byte[] p = new byte[path.length + 1]; + p[0] = '/'; + System.arraycopy(path, 0, p, 1, path.length); + return new ZipPath(this, p); + } + + // returns the list of child paths of "path" + Iterator iteratorOf(byte[] path, + DirectoryStream.Filter filter) + throws IOException + { + synchronized (lock) { + if (buildDirTree) { + IndexNode inode = getDirs().get(new EntryName(path)); + if (inode == null) + throw new NotDirectoryException(getString(path)); + List list = new ArrayList(); + IndexNode child = inode.child; + while (child != null) { + ZipPath zp = toZipPath(child.name); + if (filter == null || filter.accept(zp)) + list.add(zp); + child = child.sibling; + } + return list.iterator(); + } + + if (!isDirectory(path)) + throw new NotDirectoryException(getString(path)); + List list = new ArrayList(); + EntryName[] entries = getEntryNames(); + path = toDirectoryPath(path); + for (EntryName en :entries) { + if (!isParentOf(path, en.name)) // is "path" the parent of "name" + continue; + int off = path.length; + while (off < en.name.length) { + if (en.name[off] == '/') + break; + off++; + } + if (off < (en.name.length - 1)) + continue; + ZipPath zp = toZipPath(en.name); + if (filter == null || filter.accept(zp)) + list.add(zp); + } + return list.iterator(); + } + } + + void createDirectory(byte[] dir, FileAttribute... attrs) + throws IOException + { + checkWritable(); + dir = toDirectoryPath(dir); + synchronized (lock) { + ensureOpen(); + // pseudo root dir, or exiting dir + if (dir.length == 0 || exists(dir)) + throw new FileAlreadyExistsException(getString(dir)); + checkParents(dir); + + Entry e = new Entry(dir, Entry.NEW); + e.method = METHOD_STORED; // STORED for dir + update(e); + } + } + + void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options) + throws IOException + { + checkWritable(); + if (Arrays.equals(src, dst)) + return; // do nothing, src and dst are the same + synchronized (lock) { + Entry eSrc = getEntry0(src); // ensureOpen checked + if (eSrc == null) + throw new NoSuchFileException(getString(src)); + if (eSrc.isDir()) { // spec says to create dst dir + createDirectory(dst); + return; + } + boolean hasReplace = false; + boolean hasCopyAttrs = false; + for (CopyOption opt : options) { + if (opt == REPLACE_EXISTING) + hasReplace = true; + else if (opt == COPY_ATTRIBUTES) + hasCopyAttrs = true; + } + Entry eDst = getEntry0(dst); + if (eDst != null) { + if (!hasReplace) + throw new FileAlreadyExistsException(getString(dst)); + } else { + checkParents(dst); + } + Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry + u.name = dst; // change name + // don't touch the "nlen and elen" here. writeLOC() always + // re-calculate from "name" and "extra" for the correct length, + // copyLOCEntry however needs the original lengths to skip the + // loc header. + // u.nlen = dst.length; + if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH) + { + u.type = eSrc.type; // make it the same type + if (!deletesrc) { // if it's not "rename", just take the data + if (eSrc.bytes != null) + u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length); + else if (eSrc.file != null) { + u.file = getTempPathForEntry(null); + eSrc.file.copyTo(u.file, REPLACE_EXISTING); + } + } + } + if (!hasCopyAttrs) + u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis()); + update(u); + if (deletesrc) + updateDelete(eSrc); + } + } + + // Returns an output stream for writing the contents into the specified + // entry. + OutputStream newOutputStream(byte[] path, OpenOption... options) + throws IOException + { + checkWritable(); + boolean hasCreateNew = false; + boolean hasCreate = false; + boolean hasAppend = false; + for (OpenOption opt: options) { + if (opt == READ) + throw new IllegalArgumentException("READ not allowed"); + if (opt == CREATE_NEW) + hasCreateNew = true; + if (opt == CREATE) + hasCreate = true; + if (opt == APPEND) + hasAppend = true; + } + synchronized (lock) { + Entry e = getEntry0(path); + if (e != null) { + if (e.isDir() || hasCreateNew) + throw new FileAlreadyExistsException(getString(path)); + if (hasAppend) { + InputStream is = getInputStream(e); + OutputStream os = getOutputStream(new Entry(e, Entry.NEW)); + copyStream(is, os); + is.close(); + return os; + } + return getOutputStream(new Entry(e, Entry.NEW)); + } else { + if (!hasCreate && !hasCreateNew) + throw new NoSuchFileException(getString(path)); + checkParents(path); + return getOutputStream(new Entry(path, Entry.NEW)); + } + } + } + + // Returns an input stream for reading the contents of the specified + // file entry. + InputStream newInputStream(byte[] path) throws IOException { + synchronized (lock) { + Entry e = getEntry0(path); + if (e == null) + throw new NoSuchFileException(getString(path)); + if (e.isDir()) + throw new FileSystemException(getString(path), "is a directory", null); + return getInputStream(e); + } + } + + private void checkOptions(Set options) { + // check for options of null type and option is an intance of StandardOpenOption + for (OpenOption option : options) { + if (option == null) + throw new NullPointerException(); + if (!(option instanceof StandardOpenOption)) + throw new IllegalArgumentException(); + } + } + + // Returns a Writable/ReadByteChannel for now. Might consdier to use + // newFileChannel() instead, which dump the entry data into a regular + // file on the default file system and create a FileChannel on top of + // it. + SeekableByteChannel newByteChannel(byte[] path, + Set options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + if (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)) { + checkWritable(); + final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path, + options.toArray(new OpenOption[0]))); + long leftover = 0;; + if (options.contains(StandardOpenOption.APPEND)) { + Entry e = getEntry0(path); + if (e != null && e.size >= 0) + leftover = e.size; + } + final long offset = leftover; + return new SeekableByteChannel() { + long written = offset; + public boolean isOpen() { + return wbc.isOpen(); + } + public long position() throws IOException { + return written; + } + public SeekableByteChannel position(long pos) throws IOException { + throw new UnsupportedOperationException(); + } + public int read(ByteBuffer dst) throws IOException { + throw new UnsupportedOperationException(); + } + public SeekableByteChannel truncate(long size) throws IOException { + throw new UnsupportedOperationException(); + } + public int write(ByteBuffer src) throws IOException { + int n = wbc.write(src); + written += n; + return n; + } + public long size() throws IOException { + return written; + } + public void close() throws IOException { + wbc.close(); + } + }; + } else { + Entry e = getEntry0(path); + if (e == null || e.isDir()) + throw new NoSuchFileException(getString(path)); + final ReadableByteChannel rbc = + Channels.newChannel(getInputStream(e)); + final long size = e.size; + return new SeekableByteChannel() { + long read = 0; + public boolean isOpen() { + return rbc.isOpen(); + } + public long position() throws IOException { + return read; + } + public SeekableByteChannel position(long pos) throws IOException { + throw new UnsupportedOperationException(); + } + public int read(ByteBuffer dst) throws IOException { + return rbc.read(dst); + } + public SeekableByteChannel truncate(long size) throws IOException { + throw new NonWritableChannelException(); + } + public int write (ByteBuffer src) throws IOException { + throw new NonWritableChannelException(); + } + public long size() throws IOException { + return size; + } + public void close() throws IOException { + rbc.close(); + } + }; + } + } + + // Returns a FileChannel of the specified entry. + // + // This implementation creates a temporary file on the default file system, + // copy the entry data into it if the entry exists, and then create a + // FileChannel on top of it. + FileChannel newFileChannel(byte[] path, + Set options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + final boolean forWrite = (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)); + Entry e = getEntry0(path); + if (forWrite) { + checkWritable(); + if (e == null) { + if (!options.contains(StandardOpenOption.CREATE_NEW)) + throw new NoSuchFileException(getString(path)); + } else { + if (options.contains(StandardOpenOption.CREATE_NEW)) + throw new FileAlreadyExistsException(getString(path)); + if (e.isDir()) + throw new FileAlreadyExistsException("directory <" + + getString(path) + "> exists"); + } + options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile + } else if (e == null || e.isDir()) { + throw new NoSuchFileException(getString(path)); + } + + final boolean isFCH = (e != null && e.type == Entry.FILECH); + final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path); + final FileChannel fch = tmpfile.getFileSystem() + .provider() + .newFileChannel(tmpfile, options, attrs); + final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH); + if (forWrite) { + u.flag = FLAG_DATADESCR; + u.method = METHOD_DEFLATED; + } + // is there a better way to hook into the FileChannel's close method? + return new FileChannel() { + public int write(ByteBuffer src) throws IOException { + return fch.write(src); + } + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + return fch.write(srcs, offset, length); + } + public long position() throws IOException { + return fch.position(); + } + public FileChannel position(long newPosition) + throws IOException + { + fch.position(newPosition); + return this; + } + public long size() throws IOException { + return fch.size(); + } + public FileChannel truncate(long size) + throws IOException + { + fch.truncate(size); + return this; + } + public void force(boolean metaData) + throws IOException + { + fch.force(metaData); + } + public long transferTo(long position, long count, + WritableByteChannel target) + throws IOException + { + return fch.transferTo(position, count, target); + } + public long transferFrom(ReadableByteChannel src, + long position, long count) + throws IOException + { + return fch.transferFrom(src, position, count); + } + public int read(ByteBuffer dst) throws IOException { + return fch.read(dst); + } + public int read(ByteBuffer dst, long position) + throws IOException + { + return fch.read(dst, position); + } + public long read(ByteBuffer[] dsts, int offset, int length) + throws IOException + { + return fch.read(dsts, offset, length); + } + public int write(ByteBuffer src, long position) + throws IOException + { + return fch.write(src, position); + } + public MappedByteBuffer map(MapMode mode, + long position, long size) + throws IOException + { + throw new UnsupportedOperationException(); + } + public FileLock lock(long position, long size, boolean shared) + throws IOException + { + return fch.lock(position, size, shared); + } + public FileLock tryLock(long position, long size, boolean shared) + throws IOException + { + return fch.tryLock(position, size, shared); + } + protected void implCloseChannel() throws IOException { + fch.close(); + if (forWrite) { + u.mtime = javaToDosTime(System.currentTimeMillis()); + u.size = Attributes.readBasicFileAttributes(u.file).size(); + update(u); + } else { + if (!isFCH) // if this is a new fch for reading + removeTempPathForEntry(tmpfile); + } + } + }; + } + + // the outstanding input streams that need to be closed + private Set streams = + Collections.synchronizedSet(new HashSet()); + + // the ex-channel and ex-path that need to close when their outstanding + // input streams are all closed by the obtainers. + private Set exChClosers = new HashSet<>(); + + private Set tmppaths = new HashSet<>(); + private Path getTempPathForEntry(byte[] path) throws IOException { + Path tmpPath = createTempFileInSameDirectoryAs(zfpath); + tmppaths.add(tmpPath); + + if (path != null) { + Entry e = getEntry0(path); + if (e != null) { + InputStream is = newInputStream(path); + OutputStream os = tmpPath.newOutputStream(WRITE); + try { + copyStream(is, os); + } finally { + is.close(); + os.close(); + } + } + } + return tmpPath; + } + + private void removeTempPathForEntry(Path path) throws IOException { + path.delete(); + tmppaths.remove(path); + } + + // check if all parents really exit. ZIP spec does not require + // the existence of any "parent directory". + private void checkParents(byte[] path) throws IOException { + while ((path = getParent(path)) != null) { + if (!inodes.containsKey(new EntryName(path))) + throw new NoSuchFileException(getString(path)); + } + } + + private static byte[] getParent(byte[] path) { + int off = path.length - 1; + if (off > 0 && path[off] == '/') // isDirectory + off--; + while (off > 0 && path[off] != '/') { off--; } + if (off == 0) + return null; // top entry + return Arrays.copyOf(path, off + 1); + } + + // If "starter" is the parent directory of "path" + private static boolean isParentOf(byte[] p, byte[] c) { + final int plen = p.length; + if (plen == 0) // root dir + return true; + if (plen >= c.length) + return false; + int n = 0; + while (n < plen) { + if (p[n] != c[n]) + return false; + n++; + } + if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1)) + return false; + return true; + } + + /////////////////////////////////////////////////////////////////// + private void initZipFile() throws IOException { + ch = zfpath.newByteChannel(READ); + initCEN(); + } + + private volatile boolean isOpen = true; + private SeekableByteChannel ch; // channel to the zipfile + ByteBuffer cen; // CEN & ENDHDR + private END end; + private long locpos; // position of first LOC header (usually 0) + + // name -> pos (in cen), package private for ZipInfo + LinkedHashMap inodes; + + byte[] getBytes(String name) { + return zc.getBytes(name); + } + String getString(byte[] name) { + return zc.toString(name); + } + + protected void finalize() throws IOException { + close(); + } + + private long getDataPos(Entry e) throws IOException { + if (e.locoff == -1) { + Entry e2 = getEntry0(e.name); + if (e2 == null) + throw new ZipException("invalid loc for entry <" + e.name + ">"); + e.locoff = e2.locoff; + } + byte[] buf = new byte[LOCHDR]; + if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length) + throw new ZipException("invalid loc for entry <" + e.name + ">"); + return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf); + } + + // Reads len bytes of data from the specified offset into buf. + // Returns the total number of bytes read. + // Each/every byte read from here (except the cen, which is mapped). + private long readFullyAt(byte[] buf, int off, long len, long pos) + throws IOException + { + ByteBuffer bb = ByteBuffer.wrap(buf); + bb.position(off); + bb.limit((int)(off + len)); + return readFullyAt(bb, pos); + } + + private long readFullyAt(ByteBuffer bb, long pos) + throws IOException + { + synchronized(ch) { + return ch.position(pos).read(bb); + } + } + + // Searches for end of central directory (END) header. The contents of + // the END header will be read and placed in endbuf. Returns the file + // position of the END header, otherwise returns -1 if the END header + // was not found or an error occurred. + private END findEND() throws IOException + { + byte[] buf = new byte[READBLOCKSZ]; + long ziplen = ch.size(); + long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0; + long minPos = minHDR - (buf.length - ENDHDR); + + for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) + { + int off = 0; + if (pos < 0) { + // Pretend there are some NUL bytes before start of file + off = (int)-pos; + Arrays.fill(buf, 0, off, (byte)0); + } + int len = buf.length - off; + if (readFullyAt(buf, off, len, pos + off) != len) + zerror("zip END header not found"); + + // Now scan the block backwards for END header signature + for (int i = buf.length - ENDHDR; i >= 0; i--) { + if (buf[i+0] == (byte)'P' && + buf[i+1] == (byte)'K' && + buf[i+2] == (byte)'\005' && + buf[i+3] == (byte)'\006' && + (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) { + // Found END header + buf = Arrays.copyOfRange(buf, i, i + ENDHDR); + END end = new END(); + end.endsub = ENDSUB(buf); + end.centot = ENDTOT(buf); + end.cenlen = ENDSIZ(buf); + end.cenoff = ENDOFF(buf); + end.comlen = ENDCOM(buf); + end.endpos = pos + i; + if (end.cenlen == ZIP64_MINVAL || + end.cenoff == ZIP64_MINVAL || + end.centot == ZIP64_MINVAL32) + { + // need to find the zip64 end; + byte[] loc64 = new byte[ZIP64_LOCHDR]; + if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR) + != loc64.length) { + return end; + } + long end64pos = ZIP64_LOCOFF(loc64); + byte[] end64buf = new byte[ZIP64_ENDHDR]; + if (readFullyAt(end64buf, 0, end64buf.length, end64pos) + != end64buf.length) { + return end; + } + // end64 found, re-calcualte everything. + end.cenlen = ZIP64_ENDSIZ(end64buf); + end.cenoff = ZIP64_ENDOFF(end64buf); + end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g + end.endpos = end64pos; + } + return end; + } + } + } + zerror("zip END header not found"); + return null; //make compiler happy + } + + // Reads zip file central directory. Returns the file position of first + // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL + // then the error was a zip format error and zip->msg has the error text. + // Always pass in -1 for knownTotal; it's used for a recursive call. + private long initCEN() throws IOException { + end = findEND(); + if (end.endpos == 0) { + inodes = new LinkedHashMap(10); + locpos = 0; + return 0; // only END header present + } + if (end.cenlen > end.endpos) + zerror("invalid END header (bad central directory size)"); + long cenpos = end.endpos - end.cenlen; // position of CEN table + + // Get position of first local file (LOC) header, taking into + // account that there may be a stub prefixed to the zip file. + locpos = cenpos - end.cenoff; + if (locpos < 0) + zerror("invalid END header (bad central directory offset)"); + + // read in the CEN and END + cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR)); + if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) { + zerror("read CEN tables failed"); + } + cen.order(ByteOrder.LITTLE_ENDIAN).flip(); + + // Iterate through the entries in the central directory + inodes = new LinkedHashMap(end.centot + 1); + int pos = 0; + int limit = cen.remaining() - ENDHDR; + int i = 0; + byte[] bBuf = new byte[1024]; + while (pos < limit) { + if (CENSIG(cen, pos) != CENSIG) + zerror("invalid CEN header (bad signature)"); + int method = CENHOW(cen, pos); + int nlen = CENNAM(cen, pos); + int elen = CENEXT(cen, pos); + int clen = CENCOM(cen, pos); + if ((CENFLG(cen, pos) & 1) != 0) + zerror("invalid CEN header (encrypted entry)"); + if (method != METHOD_STORED && method != METHOD_DEFLATED) + zerror("invalid CEN header (bad compression method: " + method + ")"); + if (pos + CENHDR + nlen > limit) + zerror("invalid CEN header (bad header size)"); + if (bBuf.length < nlen) + bBuf = new byte[nlen]; + cen.position(pos + CENHDR); + byte[] name = new byte[nlen]; + cen.get(name); + inodes.put(new EntryName(name), new IndexNode(name, pos)); + // skip ext and comment + cen.position(pos += (CENHDR + nlen + elen + clen)); + i++; + } + if (cen.remaining() != ENDHDR) { + zerror("invalid CEN header (bad header size)"); + } + dirs = null; // clear the dir map + return cenpos; + } + + private void ensureOpen() throws IOException { + if (!isOpen) + throw new ClosedFileSystemException(); + } + + // Creates a new empty temporary file in the same directory as the + // specified file. A variant of File.createTempFile. + private static Path createTempFileInSameDirectoryAs(Path path) + throws IOException + { + Path parent = path.toAbsolutePath().getParent(); + String dir = (parent == null)? "." : parent.toString(); + return File.createTempFile("zipfstmp", null, new File(dir)).toPath(); + } + + ////////////////////update & sync ////////////////////////////////////// + + private boolean hasUpdate = false; + private void updateDelete(Entry e) { + EntryName en = new EntryName(e.name); + inodes.remove(en); + hasUpdate = true; + } + + private void update(Entry e) { + EntryName en = new EntryName(e.name); + inodes.put(en, e); + hasUpdate = true; + } + + // copy over the whole LOC entry (header if necessary, data and ext) from + // old zip to the new one. + private long copyLOCEntry(Entry e, boolean updateHeader, + OutputStream os, + long written, byte[] buf) + throws IOException + { + long locoff = e.locoff; // where to read + e.locoff = written; // update the e.locoff with new value + + // calculate the size need to write out + long size = 0; + // if there is A ext + if ((e.flag & FLAG_DATADESCR) != 0) { + if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL) + size = 24; + else + size = 16; + } + if (updateHeader) { // if we need update the loc header + locoff += LOCHDR + e.nlen + e.elen; // skip header + size += e.csize; + written = e.writeLOC(os) + size; + } else { + size += LOCHDR + e.nlen + e.elen + e.csize; + written = size; + } + int n; + while (size > 0 && + (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1) + { + if (size < n) + n = (int)size; + os.write(buf, 0, n); + size -= n; + locoff += n; + } + return written; + } + + // sync the zip file system, if there is any udpate + private void sync() throws IOException { + assert Thread.holdsLock(this); + + // check ex-closer + if (!exChClosers.isEmpty()) { + for (ExChannelCloser ecc : exChClosers) { + if (ecc.streams.isEmpty()) { + ecc.ch.close(); + ecc.path.delete(); + exChClosers.remove(ecc); + } + } + } + if (!hasUpdate) + return; + + Path tmpFile = createTempFileInSameDirectoryAs(zfpath); + OutputStream os = tmpFile.newOutputStream(WRITE); + ArrayList elist = new ArrayList<>(inodes.size()); + long written = 0; + byte[] buf = new byte[8192]; + Entry e = null; + + // write loc + for (IndexNode inode : inodes.values()) { + if (inode instanceof Entry) { // an updated inode + e = (Entry)inode; + try { + if (e.type == Entry.COPY) { + // entry copy: the only thing changed is the "name" + // and "nlen" in LOC header, so we udpate/rewrite the + // LOC in new file and simply copy the rest (data and + // ext) without enflating/deflating from the old zip + // file LOC entry. + written += copyLOCEntry(e, true, os, written, buf); + } else { // NEW or FILECH + e.locoff = written; + written += e.writeLOC(os); // write loc header + if (e.bytes != null) { // in-memory, deflated + os.write(e.bytes); // already + written += e.bytes.length; + } else if (e.file != null) { // tmp file + InputStream is = e.file.newInputStream(); + int n; + if (e.type == Entry.NEW) { // deflated already + while ((n = is.read(buf)) != -1) { + os.write(buf, 0, n); + written += n; + } + } else if (e.type == Entry.FILECH) { + // the data are not deflated, use ZEOS + OutputStream os2 = new EntryOutputStream(e, os); + while ((n = is.read(buf)) != -1) { + os2.write(buf, 0, n); + } + os2.close(); + written += e.csize; + if ((e.flag & FLAG_DATADESCR) != 0) + written += e.writeEXT(os); + } + is.close(); + e.file.delete(); + tmppaths.remove(e.file); + } else { + // dir, 0-length data + } + } + elist.add(e); + } catch (IOException x) { + x.printStackTrace(); // skip any in-accurate entry + } + } else { // unchanged inode + e = Entry.readCEN(cen, inode.pos); + try { + written += copyLOCEntry(e, false, os, written, buf); + elist.add(e); + } catch (IOException x) { + x.printStackTrace(); // skip any wrong entry + } + } + } + + // now write back the cen and end table + end.cenoff = written; + for (Entry entry : elist) { + written += entry.writeCEN(os); + } + end.centot = elist.size(); + end.cenlen = written - end.cenoff; + end.write(os, written); + os.close(); + + if (!streams.isEmpty()) { + // There are outstanding input streams open on existing "ch", + // so, don't close the "cha" and delete the "file for now, let + // the "ex-channel-closer" to handle them + ExChannelCloser ecc = new ExChannelCloser( + createTempFileInSameDirectoryAs(zfpath), + ch, + streams); + zfpath.moveTo(ecc.path, REPLACE_EXISTING); + exChClosers.add(ecc); + streams = Collections.synchronizedSet(new HashSet()); + } else { + ch.close(); + zfpath.delete(); + } + tmpFile.moveTo(zfpath, REPLACE_EXISTING); + hasUpdate = false; // clear + + if (isOpen) { + ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen" + initCEN(); + } + //System.out.println("->sync() done!"); + } + + private Entry getEntry0(byte[] path) throws IOException { + assert Thread.holdsLock(this); + + if (path == null) + throw new NullPointerException("path"); + if (path.length == 0) + return null; + EntryName en = new EntryName(path); + IndexNode inode = null; + synchronized (lock) { + ensureOpen(); + if ((inode = inodes.get(en)) == null) { + if (path[path.length -1] == '/') // already has a slash + return null; + path = Arrays.copyOf(path, path.length + 1); + path[path.length - 1] = '/'; + en.name(path); + if ((inode = inodes.get(en)) == null) + return null; + } + if (inode instanceof Entry) + return (Entry)inode; + return Entry.readCEN(cen, inode.pos); + } + } + + // Test if the "name" a parent directory of any entry (dir empty) + boolean isAncestor(byte[] name) { + for (Map.Entry entry : inodes.entrySet()) { + byte[] ename = entry.getKey().name; + if (isParentOf(name, ename)) + return true; + } + return false; + } + + public void deleteFile(byte[] path, boolean failIfNotExists) + throws IOException + { + checkWritable(); + synchronized(lock) { + Entry e = getEntry0(path); + if (e == null) { + if (path != null && path.length == 0) + throw new ZipException("root directory can't not be delete"); + if (failIfNotExists) + throw new NoSuchFileException(getString(path)); + } else { + if (e.isDir() && isAncestor(path)) + throw new DirectoryNotEmptyException(getString(path)); + updateDelete(e); + } + } + } + + private static void copyStream(InputStream is, OutputStream os) + throws IOException + { + byte[] copyBuf = new byte[8192]; + int n; + while ((n = is.read(copyBuf)) != -1) { + os.write(copyBuf, 0, n); + } + } + + // Returns an out stream for either + // (1) writing the contents of a new entry, if the entry exits, or + // (2) updating/replacing the contents of the specified existing entry. + private OutputStream getOutputStream(Entry e) throws IOException { + + ensureOpen(); + if (e.mtime == -1) + e.mtime = javaToDosTime(System.currentTimeMillis()); + if (e.method == -1) + e.method = METHOD_DEFLATED; // TBD: use default method + // store size, compressed size, and crc-32 in LOC header + e.flag = 0; + if (zc.isUTF8()) + e.flag |= FLAG_EFS; + OutputStream os; + if (useTempFile) { + e.file = getTempPathForEntry(null); + os = e.file.newOutputStream(WRITE); + } else { + os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192); + } + return new EntryOutputStream(e, os); + } + + private InputStream getInputStream(Entry e) + throws IOException + { + InputStream eis = null; + + if (e.type == Entry.NEW) { + if (e.bytes != null) + eis = new ByteArrayInputStream(e.bytes); + else if (e.file != null) + eis = e.file.newInputStream(); + else + throw new ZipException("update entry data is missing"); + } else if (e.type == Entry.FILECH) { + // FILECH result is un-compressed. + eis = e.file.newInputStream(); + // TBD: wrap to hook close() + // streams.add(eis); + return eis; + } else { // untouced CEN or COPY + eis = new EntryInputStream(e, ch); + } + if (e.method == METHOD_DEFLATED) { + // MORE: Compute good size for inflater stream: + long bufSize = e.size + 2; // Inflater likes a bit of slack + if (bufSize > 65536) + bufSize = 8192; + final long size = e.size;; + eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) { + + private boolean isClosed = false; + public void close() throws IOException { + if (!isClosed) { + releaseInflater(inf); + this.in.close(); + isClosed = true; + } + } + // Override fill() method to provide an extra "dummy" byte + // at the end of the input stream. This is required when + // using the "nowrap" Inflater option. (it appears the new + // zlib in 7 does not need it, but keep it for now) + protected void fill() throws IOException { + if (eof) { + throw new EOFException( + "Unexpected end of ZLIB input stream"); + } + len = this.in.read(buf, 0, buf.length); + if (len == -1) { + buf[0] = 0; + len = 1; + eof = true; + } + inf.setInput(buf, 0, len); + } + private boolean eof; + + public int available() throws IOException { + if (isClosed) + return 0; + long avail = size - inf.getBytesWritten(); + return avail > (long) Integer.MAX_VALUE ? + Integer.MAX_VALUE : (int) avail; + } + }; + } else if (e.method != METHOD_STORED) { + throw new ZipException("invalid compression method"); + } + streams.add(eis); + return eis; + } + + // Inner class implementing the input stream used to read + // a (possibly compressed) zip file entry. + private class EntryInputStream extends InputStream { + private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might + // point to a new channel after sync() + private long pos; // current position within entry data + protected long rem; // number of remaining bytes within entry + protected long size; // uncompressed size of this entry + + EntryInputStream(Entry e, SeekableByteChannel zfch) + throws IOException + { + this.zfch = zfch; + rem = e.csize; + size = e.size; + pos = getDataPos(e); + } + public int read(byte b[], int off, int len) throws IOException { + ensureOpen(); + if (rem == 0) { + return -1; + } + if (len <= 0) { + return 0; + } + if (len > rem) { + len = (int) rem; + } + // readFullyAt() + long n = 0; + ByteBuffer bb = ByteBuffer.wrap(b); + bb.position(off); + bb.limit(off + len); + synchronized(zfch) { + n = zfch.position(pos).read(bb); + } + if (n > 0) { + pos += n; + rem -= n; + } + if (rem == 0) { + close(); + } + return (int)n; + } + public int read() throws IOException { + byte[] b = new byte[1]; + if (read(b, 0, 1) == 1) { + return b[0] & 0xff; + } else { + return -1; + } + } + public long skip(long n) throws IOException { + ensureOpen(); + if (n > rem) + n = rem; + pos += n; + rem -= n; + if (rem == 0) { + close(); + } + return n; + } + public int available() { + return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem; + } + + public long size() { + return size; + } + public void close() { + rem = 0; + streams.remove(this); + } + } + + class EntryOutputStream extends DeflaterOutputStream + { + private CRC32 crc; + private Entry e; + private long written; + + EntryOutputStream(Entry e, OutputStream os) + throws IOException + { + super(os, getDeflater()); + if (e == null) + throw new NullPointerException("Zip entry is null"); + this.e = e; + crc = new CRC32(); + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if (e.type != Entry.FILECH) // only from sync + ensureOpen(); + if (off < 0 || len < 0 || off > b.length - len) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + switch (e.method) { + case METHOD_DEFLATED: + super.write(b, off, len); + break; + case METHOD_STORED: + written += len; + out.write(b, off, len); + break; + default: + throw new ZipException("invalid compression method"); + } + crc.update(b, off, len); + } + + @Override + public void close() throws IOException { + // TBD ensureOpen(); + switch (e.method) { + case METHOD_DEFLATED: + finish(); + e.size = def.getBytesRead(); + e.csize = def.getBytesWritten(); + e.crc = crc.getValue(); + break; + case METHOD_STORED: + // we already know that both e.size and e.csize are the same + e.size = e.csize = written; + e.crc = crc.getValue(); + break; + default: + throw new ZipException("invalid compression method"); + } + //crc.reset(); + if (out instanceof ByteArrayOutputStream) + e.bytes = ((ByteArrayOutputStream)out).toByteArray(); + + if (e.type == Entry.FILECH) { + releaseDeflater(def); + return; + } + super.close(); + releaseDeflater(def); + update(e); + } + } + + private static void zerror(String msg) { + throw new ZipError(msg); + } + + // Maxmum number of de/inflater we cache + private final int MAX_FLATER = 20; + // List of available Inflater objects for decompression + private List inflaters = new ArrayList<>(); + + // Gets an inflater from the list of available inflaters or allocates + // a new one. + private Inflater getInflater() { + synchronized (inflaters) { + int size = inflaters.size(); + if (size > 0) { + Inflater inf = (Inflater)inflaters.remove(size - 1); + return inf; + } else { + return new Inflater(true); + } + } + } + + // Releases the specified inflater to the list of available inflaters. + private void releaseInflater(Inflater inf) { + synchronized (inflaters) { + if (inflaters.size() < MAX_FLATER) { + inf.reset(); + inflaters.add(inf); + } else { + inf.end(); + } + } + } + + // List of available Deflater objects for compression + private List deflaters = new ArrayList<>(); + + // Gets an deflater from the list of available deflaters or allocates + // a new one. + private Deflater getDeflater() { + synchronized (deflaters) { + int size = deflaters.size(); + if (size > 0) { + Deflater def = (Deflater)deflaters.remove(size - 1); + return def; + } else { + return new Deflater(Deflater.DEFAULT_COMPRESSION, true); + } + } + } + + // Releases the specified inflater to the list of available inflaters. + private void releaseDeflater(Deflater def) { + synchronized (deflaters) { + if (inflaters.size() < MAX_FLATER) { + def.reset(); + deflaters.add(def); + } else { + def.end(); + } + } + } + + // End of central directory record + static class END { + int disknum; + int sdisknum; + int endsub; // endsub + int centot; // 4 bytes + long cenlen; // 4 bytes + long cenoff; // 4 bytes + int comlen; // comment length + byte[] comment; + + /* members of Zip64 end of central directory locator */ + int diskNum; + long endpos; + int disktot; + + void write(OutputStream os, long offset) throws IOException { + boolean hasZip64 = false; + long xlen = cenlen; + long xoff = cenoff; + if (xlen >= ZIP64_MINVAL) { + xlen = ZIP64_MINVAL; + hasZip64 = true; + } + if (xoff >= ZIP64_MINVAL) { + xoff = ZIP64_MINVAL; + hasZip64 = true; + } + int count = centot; + if (count >= ZIP64_MINVAL32) { + count = ZIP64_MINVAL32; + hasZip64 = true; + } + if (hasZip64) { + long off64 = offset; + //zip64 end of central directory record + writeInt(os, ZIP64_ENDSIG); // zip64 END record signature + writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end + writeShort(os, 45); // version made by + writeShort(os, 45); // version needed to extract + writeInt(os, 0); // number of this disk + writeInt(os, 0); // central directory start disk + writeLong(os, centot); // number of directory entires on disk + writeLong(os, centot); // number of directory entires + writeLong(os, cenlen); // length of central directory + writeLong(os, cenoff); // offset of central directory + + //zip64 end of central directory locator + writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature + writeInt(os, 0); // zip64 END start disk + writeLong(os, off64); // offset of zip64 END + writeInt(os, 1); // total number of disks (?) + } + writeInt(os, ENDSIG); // END record signature + writeShort(os, 0); // number of this disk + writeShort(os, 0); // central directory start disk + writeShort(os, count); // number of directory entries on disk + writeShort(os, count); // total number of directory entries + writeInt(os, xlen); // length of central directory + writeInt(os, xoff); // offset of central directory + if (comment != null) { // zip file comment + writeShort(os, comment.length); + writeBytes(os, comment); + } else { + writeShort(os, 0); + } + } + } + + // wrapper for the byte[] name + static class EntryName { + byte[] name; + int hashcode; // node is hashable/hashed by its name + + public EntryName (byte[] name) { + name(name); + } + + void name(byte[] name) { + this.name = name; + this.hashcode = Arrays.hashCode(name); + } + + public boolean equals(Object other) { + if (!(other instanceof EntryName)) + return false; + return Arrays.equals(name, ((EntryName)other).name); + } + + public int hashCode() { + return hashcode; + } + } + + // can simply use Integer instead, if we don't use it to + // build a internal node tree. + static class IndexNode { + byte[] name; + int pos = -1; // postion in cen table, -1 menas the + // entry does not exists in zip file + IndexNode(byte[] name, int pos) { + this.name = name; + this.pos = pos; + } + + IndexNode() {} + + IndexNode sibling; + IndexNode child; // 1st child + } + + static class Entry extends IndexNode { + + static final int CEN = 1; // entry read from cen + static final int NEW = 2; // updated contents in bytes or file + static final int FILECH = 3; // fch update in "file" + static final int COPY = 4; // copy of a CEN entry + + byte[] bytes; // updated content bytes + Path file; // use tmp file to store bytes; + int type = CEN; // default is the entry read from cen + + // entry attributes + int version; + int flag; + int method = -1; // compression method + long mtime = -1; // last modification time (in DOS time) + long atime = -1; // last access time + long ctime = -1; // create time + long crc = -1; // crc-32 of entry data + long csize = -1; // compressed size of entry data + long size = -1; // uncompressed size of entry data + int nlen; + int elen; + byte[] extra; + + // loc + long startPos; + long endPos; // exclusive + + // cen + int versionMade; + int disk; + int attrs; + long attrsEx; + long locoff; + + int clen; + byte[] comment; + + // ZIP64 flag + boolean hasZip64; + + Entry() {} + + Entry(byte[] name) { + this.name = name; + //this.nlen = name.length; + this.mtime = javaToDosTime(System.currentTimeMillis()); + this.crc = 0; + this.size = 0; + this.csize = 0; + this.method = METHOD_DEFLATED; + } + + Entry(byte[] name, int type) { + this(name); + this.type = type; + } + + Entry (byte[] name, Path file, int type) { + this(name, type); + this.file = file; + this.method = METHOD_STORED; + } + + Entry(Entry e) { + this.version = e.version; + this.name = e.name; // copyOf? + this.nlen = e.nlen; + this.ctime = e.ctime; + this.atime = e.atime; + this.mtime = e.mtime; + this.crc = e.crc; + this.size = e.size; + this.csize = e.csize; + this.method = e.method; + this.extra = (e.extra == null)? + null:Arrays.copyOf(e.extra, e.extra.length); + this.elen = e.elen; + this.versionMade = e.versionMade; + this.disk = e.disk; + this.attrs = e.attrs; + this.attrsEx = e.attrsEx; + this.locoff = e.locoff; + this.clen = e.clen; + this.comment = (e.comment == null)? + null:Arrays.copyOf(e.comment, e.comment.length); + this.startPos = e.startPos; + this.endPos = e.endPos; + this.hasZip64 = e.hasZip64;; + } + + Entry (Entry e, int type) { + this(e); + this.type = type; + } + + boolean isDir() { + return name != null && + (name.length == 0 || + name[name.length - 1] == '/'); + } + + int version() throws ZipException { + if (method == METHOD_DEFLATED) + return 20; + else if (method == METHOD_STORED) + return 10; + throw new ZipException("unsupported compression method"); + } + + ///////////////////// CEN ////////////////////// + static Entry readCEN(ByteBuffer cen, int pos) throws IOException + { + return new Entry().cen(cen, pos); + } + + private Entry cen(ByteBuffer cen, int pos) throws IOException + { + if (CENSIG(cen, pos) != CENSIG) + zerror("invalid CEN header (bad signature)"); + versionMade = CENVEM(cen, pos); + version = CENVER(cen, pos); + flag = CENFLG(cen, pos); + method = CENHOW(cen, pos); + mtime = CENTIM(cen, pos); + crc = CENCRC(cen, pos); + csize = CENSIZ(cen, pos); + size = CENLEN(cen, pos); + nlen = CENNAM(cen, pos); + elen = CENEXT(cen, pos); + clen = CENCOM(cen, pos); + disk = CENDSK(cen, pos); + attrs = CENATT(cen, pos); + attrsEx = CENATX(cen, pos); + locoff = CENOFF(cen, pos); + + cen.position(pos + CENHDR); + name = new byte[nlen]; + cen.get(name); + + if (elen > 0) { + extra = new byte[elen]; + cen.get(extra); + if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL || + locoff == ZIP64_MINVAL) { + int off = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + if (SH(extra, off) == EXTID_ZIP64) { + off += 4; + if (size == ZIP64_MINVAL) { + // if invalid zip64 extra fields, just skip + if (sz < 8 || (off + 8) > elen) + break; + size = LL(extra, off); + sz -= 8; + off += 8; + } + if (csize == ZIP64_MINVAL) { + if (sz < 8 || (off + 8) > elen) + break; + csize = LL(extra, off); + sz -= 8; + off += 8; + } + if (locoff == ZIP64_MINVAL) { + if (sz < 8 || (off + 8) > elen) + break; + locoff = LL(extra, off); + sz -= 8; + off += 8; + } + break; + } + off += (sz + 4); + } + } + } + if (clen > 0) { + comment = new byte[clen]; + cen.get(comment); + } + return this; + } + + int writeCEN(OutputStream os) throws IOException + { + int written = CENHDR; + int version0 = version(); + + long csize0 = csize; + long size0 = size; + long locoff0 = locoff; + int e64len = 0; + + // confirm size/length + nlen = (name != null) ? name.length : 0; + elen = (extra != null) ? extra.length : 0; + clen = (comment != null) ? comment.length : 0; + + boolean hasZip64 = false; + if (csize >= ZIP64_MINVAL) { + csize0 = ZIP64_MINVAL; + e64len += 8; // csize(8) + hasZip64 = true; + } + if (size >= ZIP64_MINVAL) { + size0 = ZIP64_MINVAL; // size(8) + e64len += 8; + hasZip64 = true; + } + if (locoff >= ZIP64_MINVAL) { + locoff0 = ZIP64_MINVAL; + e64len += 8; // offset(8) + hasZip64 = true; + } + writeInt(os, CENSIG); // CEN header signature + if (hasZip64) { + writeShort(os, 45); // ver 4.5 for zip64 + writeShort(os, 45); + } else { + writeShort(os, version0); // version made by + writeShort(os, version0); // version needed to extract + } + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + writeInt(os, mtime); // last modification time + writeInt(os, crc); // crc-32 + writeInt(os, csize0); // compressed size + writeInt(os, size0); // uncompressed size + writeShort(os, name.length); + + if (hasZip64) { + // + headid(2) + datasize(2) + writeShort(os, e64len + 4 + elen); + } else { + writeShort(os, elen); + } + if (comment != null) { + writeShort(os, Math.min(clen, 0xffff)); + } else { + writeShort(os, 0); + } + writeShort(os, 0); // starting disk number + writeShort(os, 0); // internal file attributes (unused) + writeInt(os, 0); // external file attributes (unused) + writeInt(os, locoff0); // relative offset of local header + writeBytes(os, name); + if (hasZip64) { + writeShort(os, EXTID_ZIP64);// Zip64 extra + writeShort(os, e64len); + if (size0 == ZIP64_MINVAL) + writeLong(os, size); + if (csize0 == ZIP64_MINVAL) + writeLong(os, csize); + if (locoff0 == ZIP64_MINVAL) + writeLong(os, locoff); + } + if (extra != null) { + writeBytes(os, extra); + } + if (comment != null) { + //TBD: 0, Math.min(commentBytes.length, 0xffff)); + writeBytes(os, comment); + } + return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0); + } + + ///////////////////// LOC ////////////////////// + static Entry readLOC(ZipFileSystem zf, long pos) + throws IOException + { + return readLOC(zf, pos, new byte[1024]); + } + + static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf) + throws IOException + { + return new Entry().loc(zf, pos, buf); + } + + Entry loc(ZipFileSystem zf, long pos, byte[] buf) + throws IOException + { + assert (buf.length >= LOCHDR); + if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) { + throw new ZipException("loc: reading failed"); + } + if (LOCSIG(buf) != LOCSIG) { + throw new ZipException("loc: wrong sig ->" + + Long.toString(LOCSIG(buf), 16)); + } + startPos = pos; + version = LOCVER(buf); + flag = LOCFLG(buf); + method = LOCHOW(buf); + mtime = LOCTIM(buf); + crc = LOCCRC(buf); + csize = LOCSIZ(buf); + size = LOCLEN(buf); + nlen = LOCNAM(buf); + elen = LOCEXT(buf); + + name = new byte[nlen]; + if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) { + throw new ZipException("loc: name reading failed"); + } + if (elen > 0) { + extra = new byte[elen]; + if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen) + != elen) { + throw new ZipException("loc: ext reading failed"); + } + } + pos += (LOCHDR + nlen + elen); + if ((flag & FLAG_DATADESCR) != 0) { + // Data Descriptor + Entry e = zf.getEntry0(name); // get the size/csize from cen + if (e == null) + throw new ZipException("loc: name not found in cen"); + size = e.size; + csize = e.csize; + pos += (method == METHOD_STORED ? size : csize); + if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL) + pos += 24; + else + pos += 16; + } else { + boolean hasZip64 = false; + if (extra != null && + (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) { + // zip64 ext: must include both size and csize + int off = 0; + while (off + 20 < elen) { // HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + if (SH(extra, off) == EXTID_ZIP64 && sz == 16) { + size = LL(extra, off + 4); + csize = LL(extra, off + 12); + hasZip64 = true; + break; + } + off += (sz + 4); + } + } + pos += (method == METHOD_STORED ? size : csize); + } + endPos = pos; + return this; + } + + int writeLOC(OutputStream os) + throws IOException + { + writeInt(os, LOCSIG); // LOC header signature + + int version = version(); + if ((flag & FLAG_DATADESCR) != 0) { + writeShort(os, version()); // version needed to extract + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + writeInt(os, mtime); // last modification time + + // store size, uncompressed size, and crc-32 in data descriptor + // immediately following compressed entry data + writeInt(os, 0); + writeInt(os, 0); + writeInt(os, 0); + } else { + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { + hasZip64 = true; + writeShort(os, 45); // ver 4.5 for zip64 + } else { + writeShort(os, version()); // version needed to extract + } + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + writeInt(os, mtime); // last modification time + writeInt(os, crc); // crc-32 + if (hasZip64) { + writeInt(os, ZIP64_MINVAL); + writeInt(os, ZIP64_MINVAL); + //TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8) + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + } + } + writeShort(os, name.length); + writeShort(os, elen + (hasZip64 ? 20 : 0)); + writeBytes(os, name); + if (hasZip64) { + // TBD: should we update extra directory? + writeShort(os, EXTID_ZIP64); + writeShort(os, 16); + writeLong(os, size); + writeLong(os, csize); + } + if (extra != null) { + writeBytes(os, extra); + } + return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0); + } + + // Data Descriptior + int writeEXT(OutputStream os) + throws IOException + { + writeInt(os, EXTSIG); // EXT header signature + writeInt(os, crc); // crc-32 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { + writeLong(os, csize); + writeLong(os, size); + return 24; + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + return 16; + } + } + + // read NTFS, UNIX and ZIP64 data from cen.extra + void readExtra() { + if (extra == null) + return; + int elen = extra.length; + int off = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + int tag = SH(extra, off); + off += 4; + int pos = off; + if (pos + sz > elen) // invalid data + break; + switch (tag) { + case EXTID_ZIP64 : + if (size == ZIP64_MINVAL) { + if (pos + 8 > elen) // invalid zip64 extra + break; // fields, just skip + size = LL(extra, pos); + pos += 8; + } + if (csize == ZIP64_MINVAL) { + if (pos + 8 > elen) + break; + csize = LL(extra, pos); + pos += 8; + } + if (locoff == ZIP64_MINVAL) { + if (pos + 8 > elen) + break; + locoff = LL(extra, pos); + pos += 8; + } + break; + case EXTID_NTFS: + pos += 4; // reserved 4 bytes + if (SH(extra, pos) != 0x0001) + break; + if (SH(extra, pos + 2) != 24) + break; + mtime = LL(extra, pos + 4); + atime = LL(extra, pos + 12); + ctime = LL(extra, pos + 20); + break; + case EXTID_UNIX: + atime = LG(extra, pos); + mtime = LG(extra, pos + 4); + break; + default: // unknow + } + off += sz; + } + } + } + + private static class ExChannelCloser { + Path path; + SeekableByteChannel ch; + Set streams; + ExChannelCloser(Path path, + SeekableByteChannel ch, + Set streams) + { + this.path = path; + this.ch = ch; + this.streams = streams; + } + } + + // ZIP directory has two issues: + // (1) ZIP spec does not require the ZIP file to include + // directory entry + // (2) all entries are not stored/organized in a "tree" + // structure. + // A possible solution is to build the node tree ourself as + // implemented below. + private HashMap dirs; + private IndexNode root; + private IndexNode addToDir(EntryName child) { + IndexNode cinode = dirs.get(child); + if (cinode != null) + return cinode; + + byte[] cname = child.name; + byte[] pname = getParent(cname); + IndexNode pinode; + + if (pname != null) + pinode = addToDir(new EntryName(pname)); + else + pinode = root; + cinode = inodes.get(child); + if (cname[cname.length -1] != '/') { // not a dir + cinode.sibling = pinode.child; + pinode.child = cinode; + return null; + } + cinode = dirs.get(child); + if (cinode == null) // pseudo directry entry + cinode = new IndexNode(cname, -1); + cinode.sibling = pinode.child; + pinode.child = cinode; + + dirs.put(child, cinode); + return cinode; + } + + private HashMap getDirs() + throws IOException + { + if (hasUpdate) + sync(); + if (dirs != null) + return dirs; + dirs = new HashMap(); + byte[] empty = new byte[0]; + root = new IndexNode(empty, -1); + dirs.put(new EntryName(empty), root); + + EntryName[] names = inodes.keySet().toArray(new EntryName[0]); + int i = names.length; + while (--i >= 0) { + addToDir(names[i]); + } + // for (int i EntryName en : inodes.keySet()) { + // addToDir(en); + // } + return dirs; + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java new file mode 100644 index 00000000000..a43b2cf7de3 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.FileRef; +import java.nio.file.FileSystem; +import java.nio.file.FileSystemNotFoundException; +import java.nio.file.FileSystemAlreadyExistsException; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.ProviderMismatchException; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.spi.FileSystemProvider; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/* + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileSystemProvider extends FileSystemProvider { + private final Map filesystems = new HashMap<>(); + + public ZipFileSystemProvider() {} + + @Override + public String getScheme() { + return "zip"; + } + + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) + .toAbsolutePath(); + } catch (URISyntaxException e) { + throw new AssertionError(e); //never thrown + } + } + + @Override + public FileSystem newFileSystem(URI uri, Map env) + throws IOException + { + return newFileSystem(uriToPath(uri), env); + } + + @Override + public FileSystem newFileSystem(FileRef file, Map env) + throws IOException + { + if (!(file instanceof Path)) + throw new UnsupportedOperationException(); + Path path = (Path)file; + if (!path.toUri().getScheme().equalsIgnoreCase("file")) { + throw new UnsupportedOperationException(); + } + return newFileSystem(path, env); + } + + private FileSystem newFileSystem(Path path, Map env) + throws IOException + { + synchronized(filesystems) { + if (filesystems.containsKey(path)) + throw new FileSystemAlreadyExistsException(); + ZipFileSystem zipfs = new ZipFileSystem(this, path, env); + filesystems.put(path, zipfs); + return zipfs; + } + } + + @Override + public Path getPath(URI uri) { + FileSystem fs = getFileSystem(uri); + String fragment = uri.getFragment(); + if (fragment == null) { + throw new IllegalArgumentException("URI: " + + uri + + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR"); + } + return fs.getPath(fragment); + } + + @Override + public FileChannel newFileChannel(Path path, + Set options, + FileAttribute... attrs) + throws IOException + { + if (path == null) + throw new NullPointerException("path is null"); + if (path instanceof ZipPath) + return ((ZipPath)path).newFileChannel(options, attrs); + throw new ProviderMismatchException(); + } + + @Override + public FileSystem getFileSystem(URI uri) { + synchronized (filesystems) { + ZipFileSystem zipfs = filesystems.get(uriToPath(uri)); + if (zipfs == null) + throw new FileSystemNotFoundException(); + return zipfs; + } + } + + void removeFileSystem(Path zfpath) { + synchronized (filesystems) { + filesystems.remove(zfpath); + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java new file mode 100644 index 00000000000..741376daf0d --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.PrintStream; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import com.sun.nio.zipfs.ZipFileSystem.Entry; +import static com.sun.nio.zipfs.ZipConstants.*; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * Print the loc and cen tables of the ZIP file + * + * @author Xueming Shen + */ + +public class ZipInfo { + + public static void main(String[] args) throws Throwable { + if (args.length < 2) { + print("Usage: java ZipInfo [cen|loc] zfname"); + } else { + Map env = Collections.emptyMap(); + ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider() + .newFileSystem(Paths.get(args[1]), env)); + + long pos = 0; + + if ("loc".equals(args[0])) { + print("[Local File Header]%n"); + byte[] buf = new byte[1024]; + for (int i = 0; i < zfs.getEntryNames().length; i++) { + Entry loc = Entry.readLOC(zfs, pos, buf); + print("--------loc[%x]--------%n", pos); + printLOC(loc); + pos = loc.endPos; + } + } if ("cen".equals(args[0])) { + int i = 0; + Iterator itr = zfs.inodes.values().iterator(); + print("[Central Directory Header]%n"); + while (itr.hasNext()) { + Entry cen = Entry.readCEN(zfs.cen, itr.next().pos); + print("--------cen[%d]--------%n", i); + printCEN(cen); + i++; + } + } + zfs.close(); + } + } + + static void print(String fmt, Object... objs) { + System.out.printf(fmt, objs); + } + + static void printLOC(Entry loc) { + print(" [%x, %x]%n", loc.startPos, loc.endPos); + print(" Signature : %8x%n", LOCSIG); + print(" Version : %4x [%d.%d]%n", + loc.version, loc. version/10, loc. version%10); + print(" Flag : %4x%n", loc.flag); + print(" Method : %4x%n", loc. method); + print(" LastMTime : %8x [%tc]%n", + loc.mtime, dosToJavaTime(loc.mtime)); + print(" CRC : %8x%n", loc.crc); + print(" CSize : %8x%n", loc.csize); + print(" Size : %8x%n", loc.size); + print(" NameLength : %4x [%s]%n", + loc.nlen, new String(loc.name)); + print(" ExtraLength : %4x%n", loc.elen); + if (loc.hasZip64) + print(" *ZIP64*%n"); + } + + static void printCEN(Entry cen) { + print(" Signature : %08x%n", CENSIG); + print(" VerMadeby : %4x [%d.%d]%n", + cen.versionMade, cen.versionMade/10, cen.versionMade%10); + print(" VerExtract : %4x [%d.%d]%n", + cen.version, cen.version/10, cen.version%10); + print(" Flag : %4x%n", cen.flag); + print(" Method : %4x%n", cen.method); + print(" LastMTime : %8x [%tc]%n", + cen.mtime, dosToJavaTime(cen.mtime)); + print(" CRC : %8x%n", cen.crc); + print(" CSize : %8x%n", cen.csize); + print(" Size : %8x%n", cen.size); + print(" NameLen : %4x [%s]%n", + cen.nlen, new String(cen.name)); + print(" ExtraLen : %4x%n", cen.elen); + print(" CommentLen : %4x%n", cen.clen); + print(" DiskStart : %4x%n", cen.disk); + print(" Attrs : %4x%n", cen.attrs); + print(" AttrsEx : %8x%n", cen.attrsEx); + print(" LocOff : %8x%n", cen.locoff); + if (cen.hasZip64) + print(" *ZIP64*%n"); + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java new file mode 100644 index 00000000000..1ceab8fc81a --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java @@ -0,0 +1,964 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.File; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.*; +import java.nio.file.DirectoryStream.Filter; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileTime; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal + */ + +public class ZipPath extends Path { + + private final ZipFileSystem zfs; + private final byte[] path; + private volatile int[] offsets; + private int hashcode = 0; // cached hashcode (created lazily) + + ZipPath(ZipFileSystem zfs, byte[] path) { + this(zfs, path, false); + } + + ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) + { + this.zfs = zfs; + if (normalized) + this.path = path; + else + this.path = normalize(path); + } + + @Override + public ZipPath getRoot() { + if (this.isAbsolute()) + return new ZipPath(zfs, new byte[]{path[0]}); + else + return null; + } + + @Override + public Path getName() { + initOffsets(); + int count = offsets.length; + if (count == 0) + return null; // no elements so no name + if (count == 1 && path[0] != '/') + return this; + int lastOffset = offsets[count-1]; + int len = path.length - lastOffset; + byte[] result = new byte[len]; + System.arraycopy(path, lastOffset, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath getParent() { + initOffsets(); + int count = offsets.length; + if (count == 0) // no elements so no parent + return null; + int len = offsets[count-1] - 1; + if (len <= 0) // parent is root only (may be null) + return getRoot(); + byte[] result = new byte[len]; + System.arraycopy(path, 0, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public int getNameCount() { + initOffsets(); + return offsets.length; + } + + @Override + public ZipPath getName(int index) { + initOffsets(); + if (index < 0 || index >= offsets.length) + throw new IllegalArgumentException(); + int begin = offsets[index]; + int len; + if (index == (offsets.length-1)) + len = path.length - begin; + else + len = offsets[index+1] - begin - 1; + // construct result + byte[] result = new byte[len]; + System.arraycopy(path, begin, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath subpath(int beginIndex, int endIndex) { + initOffsets(); + if (beginIndex < 0 || + beginIndex >= offsets.length || + endIndex > offsets.length || + beginIndex >= endIndex) + throw new IllegalArgumentException(); + + // starting offset and length + int begin = offsets[beginIndex]; + int len; + if (endIndex == offsets.length) + len = path.length - begin; + else + len = offsets[endIndex] - begin - 1; + // construct result + byte[] result = new byte[len]; + System.arraycopy(path, begin, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath toRealPath(boolean resolveLinks) throws IOException { + ZipPath realPath = new ZipPath(zfs, getResolvedPath()); + realPath.checkAccess(); + return realPath; + } + + @Override + public boolean isHidden() { + return false; + } + + @Override + public ZipPath toAbsolutePath() { + if (isAbsolute()) { + return this; + } else { + //add / bofore the existing path + byte[] defaultdir = zfs.getDefaultDir().path; + int defaultlen = defaultdir.length; + boolean endsWith = (defaultdir[defaultlen - 1] == '/'); + byte[] t = null; + if (endsWith) + t = new byte[defaultlen + path.length]; + else + t = new byte[defaultlen + 1 + path.length]; + System.arraycopy(defaultdir, 0, t, 0, defaultlen); + if (!endsWith) + t[defaultlen++] = '/'; + System.arraycopy(path, 0, t, defaultlen, path.length); + return new ZipPath(zfs, t, true); // normalized + } + } + + @Override + public URI toUri() { + String zfPath = zfs.toString(); + if (File.separatorChar == '\\') // replace all separators by '/' + zfPath = "/" + zfPath.replace("\\", "/"); + try { + return new URI("zip", "", + zfPath, + zfs.getString(toAbsolutePath().path)); + } catch (Exception ex) { + throw new AssertionError(ex); + } + } + + private boolean equalsNameAt(ZipPath other, int index) { + int mbegin = offsets[index]; + int mlen = 0; + if (index == (offsets.length-1)) + mlen = path.length - mbegin; + else + mlen = offsets[index + 1] - mbegin - 1; + int obegin = other.offsets[index]; + int olen = 0; + if (index == (other.offsets.length - 1)) + olen = other.path.length - obegin; + else + olen = other.offsets[index + 1] - obegin - 1; + if (mlen != olen) + return false; + int n = 0; + while(n < mlen) { + if (path[mbegin + n] != other.path[obegin + n]) + return false; + n++; + } + return true; + } + + @Override + public Path relativize(Path other) { + final ZipPath o = checkPath(other); + if (o.equals(this)) + return null; + if (/* this.getFileSystem() != o.getFileSystem() || */ + this.isAbsolute() != o.isAbsolute()) { + throw new IllegalArgumentException(); + } + int mc = this.getNameCount(); + int oc = o.getNameCount(); + int n = Math.min(mc, oc); + int i = 0; + while (i < n) { + if (!equalsNameAt(o, i)) + break; + i++; + } + int dotdots = mc - i; + int len = dotdots * 3 - 1; + if (i < oc) + len += (o.path.length - o.offsets[i] + 1); + byte[] result = new byte[len]; + + int pos = 0; + while (dotdots > 0) { + result[pos++] = (byte)'.'; + result[pos++] = (byte)'.'; + if (pos < len) // no tailing slash at the end + result[pos++] = (byte)'/'; + dotdots--; + } + if (i < oc) + System.arraycopy(o.path, o.offsets[i], + result, pos, + o.path.length - o.offsets[i]); + return new ZipPath(getFileSystem(), result); + } + + @Override + public ZipFileSystem getFileSystem() { + return zfs; + } + + @Override + public boolean isAbsolute() { + return (this.path[0] == '/'); + } + + @Override + public ZipPath resolve(Path other) { + if (other == null) + return this; + final ZipPath o = checkPath(other); + if (o.isAbsolute()) + return o; + byte[] resolved = null; + if (this.path[path.length - 1] == '/') { + resolved = new byte[path.length + o.path.length]; + System.arraycopy(path, 0, resolved, 0, path.length); + System.arraycopy(o.path, 0, resolved, path.length, o.path.length); + } else { + resolved = new byte[path.length + 1 + o.path.length]; + System.arraycopy(path, 0, resolved, 0, path.length); + resolved[path.length] = '/'; + System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length); + } + return new ZipPath(zfs, resolved); + } + + @Override + public ZipPath resolve(String other) { + return resolve(getFileSystem().getPath(other)); + } + + @Override + public boolean startsWith(Path other) { + final ZipPath o = checkPath(other); + if (o.isAbsolute() != this.isAbsolute()) + return false; + final int oCount = o.getNameCount(); + if (getNameCount() < oCount) + return false; + for (int i = 0; i < oCount; i++) { + if (!o.getName(i).equals(getName(i))) + return false; + } + return true; + } + + @Override + public boolean endsWith(Path other) { + final ZipPath o = checkPath(other); + if (o.isAbsolute()) + return this.isAbsolute() ? this.equals(o) : false; + int i = o.getNameCount(); + int j = this.getNameCount(); + if (j < i) + return false; + for (--i, --j; i >= 0; i--, j--) { + if (!o.getName(i).equals(this.getName(j))) + return false; + } + return true; + } + + @Override + public Path normalize() { + byte[] resolved = getResolved(); + if (resolved == path) // no change + return this; + if (resolved.length == 0) + return null; + return new ZipPath(zfs, resolved, true); + } + + private ZipPath checkPath(Path path) { + if (path == null) + throw new NullPointerException(); + if (!(path instanceof ZipPath)) + throw new ProviderMismatchException(); + return (ZipPath) path; + } + + // create offset list if not already created + private void initOffsets() { + if (offsets == null) { + int count, index; + // count names + count = 0; + index = 0; + while (index < path.length) { + byte c = path[index++]; + if (c != '/') { + count++; + while (index < path.length && path[index] != '/') + index++; + } + } + // populate offsets + int[] result = new int[count]; + count = 0; + index = 0; + while (index < path.length) { + byte c = path[index]; + if (c == '/') { + index++; + } else { + result[count++] = index++; + while (index < path.length && path[index] != '/') + index++; + } + } + synchronized (this) { + if (offsets == null) + offsets = result; + } + } + } + + // resolved path for locating zip entry inside the zip file, + // the result path does not contain ./ and .. components + private volatile byte[] resolved = null; + byte[] getResolvedPath() { + byte[] r = resolved; + if (r == null) { + if (isAbsolute()) + r = getResolved(); + else + r = toAbsolutePath().getResolvedPath(); + if (r[0] == '/') + r = Arrays.copyOfRange(r, 1, r.length); + resolved = r; + } + return resolved; + } + + // removes redundant slashs, replace "\" to zip separator "/" + // and check for invalid characters + private byte[] normalize(byte[] path) { + if (path.length == 0) + return path; + byte prevC = 0; + for (int i = 0; i < path.length; i++) { + byte c = path[i]; + if (c == '\\') + return normalize(path, i); + if (c == (byte)'/' && prevC == '/') + return normalize(path, i - 1); + if (c == '\u0000') + throw new InvalidPathException(zfs.getString(path), + "Path: nul character not allowed"); + prevC = c; + } + return path; + } + + private byte[] normalize(byte[] path, int off) { + byte[] to = new byte[path.length]; + int n = 0; + while (n < off) { + to[n] = path[n]; + n++; + } + int m = n; + byte prevC = 0; + while (n < path.length) { + byte c = path[n++]; + if (c == (byte)'\\') + c = (byte)'/'; + if (c == (byte)'/' && prevC == (byte)'/') + continue; + if (c == '\u0000') + throw new InvalidPathException(zfs.getString(path), + "Path: nul character not allowed"); + to[m++] = c; + prevC = c; + } + if (m > 1 && to[m - 1] == '/') + m--; + return (m == to.length)? to : Arrays.copyOf(to, m); + } + + // Remove DotSlash(./) and resolve DotDot (..) components + private byte[] getResolved() { + if (path.length == 0) + return path; + for (int i = 0; i < path.length; i++) { + byte c = path[i]; + if (c == (byte)'.') + return resolve0(); + } + return path; + } + + // TBD: performance, avoid initOffsets + private byte[] resolve0() { + byte[] to = new byte[path.length]; + int nc = getNameCount(); + int[] lastM = new int[nc]; + int lastMOff = -1; + int m = 0; + for (int i = 0; i < nc; i++) { + int n = offsets[i]; + int len = (i == offsets.length - 1)? + (path.length - n):(offsets[i + 1] - n - 1); + if (len == 1 && path[n] == (byte)'.') + continue; + if (len == 2 && path[n] == '.' && path[n + 1] == '.') { + if (lastMOff >= 0) { + m = lastM[lastMOff--]; // retreat + continue; + } + if (path[0] == '/') { // "/../xyz" skip + if (m == 0) + to[m++] = '/'; + } else { // "../xyz" -> "../xyz" + if (m != 0 && to[m-1] != '/') + to[m++] = '/'; + while (len-- > 0) + to[m++] = path[n++]; + } + continue; + } + if (m == 0 && path[0] == '/' || // absolute path + m != 0 && to[m-1] != '/') { // not the first name + to[m++] = '/'; + } + lastM[++lastMOff] = m; + while (len-- > 0) + to[m++] = path[n++]; + } + if (m > 1 && to[m - 1] == '/') + m--; + return (m == to.length)? to : Arrays.copyOf(to, m); + } + + @Override + public String toString() { + return zfs.getString(path); + } + + @Override + public int hashCode() { + int h = hashcode; + if (h == 0) + hashcode = h = Arrays.hashCode(path); + return h; + } + + @Override + public boolean equals(Object obj) { + return obj != null && + obj instanceof ZipPath && + this.zfs == ((ZipPath)obj).zfs && + compareTo((Path) obj) == 0; + } + + @Override + public int compareTo(Path other) { + final ZipPath o = checkPath(other); + int len1 = this.path.length; + int len2 = o.path.length; + + int n = Math.min(len1, len2); + byte v1[] = this.path; + byte v2[] = o.path; + + int k = 0; + while (k < n) { + int c1 = v1[k] & 0xff; + int c2 = v2[k] & 0xff; + if (c1 != c2) + return c1 - c2; + k++; + } + return len1 - len2; + } + + @Override + public Path createSymbolicLink( + Path target, FileAttribute... attrs) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Path createLink( + Path existing) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Path readSymbolicLink() throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Path createDirectory(FileAttribute... attrs) + throws IOException + { + zfs.createDirectory(getResolvedPath(), attrs); + return this; + } + + public final Path createFile(FileAttribute... attrs) + throws IOException + { + OutputStream os = newOutputStream(CREATE_NEW, WRITE); + try { + os.close(); + } catch (IOException x) {} + return this; + } + + @Override + public InputStream newInputStream(OpenOption... options) + throws IOException { + if (options.length > 0) { + for (OpenOption opt : options) { + if (opt != READ) + throw new UnsupportedOperationException("'" + opt + "' not allowed"); + } + } + return zfs.newInputStream(getResolvedPath()); + } + + private static final DirectoryStream.Filter acceptAllFilter = + new DirectoryStream.Filter() { + @Override public boolean accept(Path entry) { return true; } + }; + + @Override + public final DirectoryStream newDirectoryStream() throws IOException { + return newDirectoryStream(acceptAllFilter); + } + + @Override + public DirectoryStream newDirectoryStream(Filter filter) + throws IOException + { + return new ZipDirectoryStream(this, filter); + } + + @Override + public final DirectoryStream newDirectoryStream(String glob) + throws IOException + { + // avoid creating a matcher if all entries are required. + if (glob.equals("*")) + return newDirectoryStream(); + + // create a matcher and return a filter that uses it. + final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob); + DirectoryStream.Filter filter = new DirectoryStream.Filter() { + @Override + public boolean accept(Path entry) { + return matcher.matches(entry.getName()); + } + }; + return newDirectoryStream(filter); + } + + @Override + public final void delete() throws IOException { + zfs.deleteFile(getResolvedPath(), true); + } + + @Override + public final void deleteIfExists() throws IOException { + zfs.deleteFile(getResolvedPath(), false); + } + + ZipFileAttributes getAttributes() throws IOException + { + ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath()); + if (zfas == null) + throw new NoSuchFileException(toString()); + return zfas; + } + + @Override + @SuppressWarnings("unchecked") + public V getFileAttributeView(Class type, + LinkOption... options) + { + return (V)ZipFileAttributeView.get(this, type); + } + + @Override + public void setAttribute(String attribute, + Object value, + LinkOption... options) + throws IOException + { + String type = null; + String attr = null; + int colonPos = attribute.indexOf(':'); + if (colonPos == -1) { + type = "basic"; + attr = attribute; + } else { + type = attribute.substring(0, colonPos++); + attr = attribute.substring(colonPos); + } + ZipFileAttributeView view = ZipFileAttributeView.get(this, type); + if (view == null) + throw new UnsupportedOperationException("view <" + view + "> is not supported"); + view.setAttribute(attr, value); + } + + void setTimes(FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + zfs.setTimes(getResolvedPath(), mtime, atime, ctime); + } + + private Object getAttributesImpl(String attribute, boolean domap) + throws IOException + { + String view = null; + String attr = null; + int colonPos = attribute.indexOf(':'); + if (colonPos == -1) { + view = "basic"; + attr = attribute; + } else { + view = attribute.substring(0, colonPos++); + attr = attribute.substring(colonPos); + } + ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view); + if (zfv == null) { + throw new UnsupportedOperationException("view not supported"); + } + return zfv.getAttribute(attr, domap); + } + + @Override + public Object getAttribute(String attribute, LinkOption... options) + throws IOException + { + return getAttributesImpl(attribute, false); + } + + @Override + public Map readAttributes(String attribute, LinkOption... options) + throws IOException + { + return (Map)getAttributesImpl(attribute, true); + } + + @Override + public FileStore getFileStore() throws IOException { + // each ZipFileSystem only has one root (as requested for now) + if (exists()) + return zfs.getFileStore(this); + throw new NoSuchFileException(zfs.getString(path)); + } + + @Override + public boolean isSameFile(Path other) throws IOException { + if (other == null || + this.getFileSystem() != other.getFileSystem()) + return false; + this.checkAccess(); + other.checkAccess(); + return Arrays.equals(this.getResolvedPath(), + ((ZipPath)other).getResolvedPath()); + } + + public WatchKey register( + WatchService watcher, + WatchEvent.Kind[] events, + WatchEvent.Modifier... modifiers) { + if (watcher == null || events == null || modifiers == null) { + throw new NullPointerException(); + } + throw new UnsupportedOperationException(); + } + + @Override + public WatchKey register(WatchService watcher, WatchEvent.Kind... events) { + return register(watcher, events, new WatchEvent.Modifier[0]); + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int i = 0; + + @Override + public boolean hasNext() { + return (i < getNameCount()); + } + + @Override + public Path next() { + if (i < getNameCount()) { + Path result = getName(i); + i++; + return result; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new ReadOnlyFileSystemException(); + } + }; + } + + @Override + public SeekableByteChannel newByteChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newByteChannel(getResolvedPath(), options, attrs); + } + + + FileChannel newFileChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newFileChannel(getResolvedPath(), options, attrs); + } + + @Override + public SeekableByteChannel newByteChannel(OpenOption... options) + throws IOException { + Set set = new HashSet(options.length); + Collections.addAll(set, options); + return newByteChannel(set); + } + + @Override + public void checkAccess(AccessMode... modes) throws IOException { + boolean w = false; + boolean x = false; + for (AccessMode mode : modes) { + switch (mode) { + case READ: + break; + case WRITE: + w = true; + break; + case EXECUTE: + x = true; + break; + default: + throw new UnsupportedOperationException(); + } + } + ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath()); + if (attrs == null && (path.length != 1 || path[0] != '/')) + throw new NoSuchFileException(toString()); + if (w) { + if (zfs.isReadOnly()) + throw new AccessDeniedException(toString()); + } + if (x) + throw new AccessDeniedException(toString()); + + } + + @Override + public boolean exists() { + if (path.length == 1 && path[0] == '/') + return true; + try { + return zfs.exists(getResolvedPath()); + } catch (IOException x) {} + return false; + } + + @Override + public boolean notExists() { + return !exists(); + } + + + @Override + public OutputStream newOutputStream(OpenOption... options) + throws IOException + { + if (options.length == 0) + return zfs.newOutputStream(getResolvedPath(), + CREATE_NEW, WRITE); + return zfs.newOutputStream(getResolvedPath(), options); + } + + @Override + public Path moveTo(Path target, CopyOption... options) + throws IOException + { + if (this.zfs.provider() == target.getFileSystem().provider() && + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile())) + { + zfs.copyFile(true, + getResolvedPath(), + ((ZipPath)target).getResolvedPath(), + options); + } else { + copyToTarget(target, options); + delete(); + } + return target; + } + + @Override + public Path copyTo(Path target, CopyOption... options) + throws IOException + { + if (this.zfs.provider() == target.getFileSystem().provider() && + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile())) + { + zfs.copyFile(false, + getResolvedPath(), + ((ZipPath)target).getResolvedPath(), + options); + } else { + copyToTarget(target, options); + } + return target; + } + + private void copyToTarget(Path target, CopyOption... options) + throws IOException + { + boolean replaceExisting = false; + boolean copyAttrs = false; + for (CopyOption opt : options) { + if (opt == REPLACE_EXISTING) + replaceExisting = true; + else if (opt == COPY_ATTRIBUTES) + copyAttrs = false; + } + // attributes of source file + ZipFileAttributes zfas = getAttributes(); + // check if target exists + boolean exists; + if (replaceExisting) { + try { + target.deleteIfExists(); + exists = false; + } catch (DirectoryNotEmptyException x) { + exists = true; + } + } else { + exists = target.exists(); + } + if (exists) + throw new FileAlreadyExistsException(target.toString()); + + if (zfas.isDirectory()) { + // create directory or file + target.createDirectory(); + } else { + InputStream is = zfs.newInputStream(getResolvedPath()); + try { + OutputStream os = target.newOutputStream(); + try { + byte[] buf = new byte[8192]; + int n = 0; + while ((n = is.read(buf)) != -1) { + os.write(buf, 0, n); + } + } finally { + os.close(); + } + } finally { + is.close(); + } + } + if (copyAttrs) { + BasicFileAttributeView view = + target.getFileAttributeView(BasicFileAttributeView.class); + try { + view.setTimes(zfas.lastModifiedTime(), null, null); + } catch (IOException x) { + // rollback? + try { + target.delete(); + } catch (IOException ignore) { } + throw x; + } + } + } +} diff --git a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java new file mode 100644 index 00000000000..b3106e09fa3 --- /dev/null +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Date; +import java.util.regex.PatternSyntaxException; + +/** + * + * @author Xueming Shen + */ + +class ZipUtils { + + /* + * Writes a 16-bit short to the output stream in little-endian byte order. + */ + public static void writeShort(OutputStream os, int v) throws IOException { + os.write((v >>> 0) & 0xff); + os.write((v >>> 8) & 0xff); + } + + /* + * Writes a 32-bit int to the output stream in little-endian byte order. + */ + public static void writeInt(OutputStream os, long v) throws IOException { + os.write((int)((v >>> 0) & 0xff)); + os.write((int)((v >>> 8) & 0xff)); + os.write((int)((v >>> 16) & 0xff)); + os.write((int)((v >>> 24) & 0xff)); + } + + /* + * Writes a 64-bit int to the output stream in little-endian byte order. + */ + public static void writeLong(OutputStream os, long v) throws IOException { + os.write((int)((v >>> 0) & 0xff)); + os.write((int)((v >>> 8) & 0xff)); + os.write((int)((v >>> 16) & 0xff)); + os.write((int)((v >>> 24) & 0xff)); + os.write((int)((v >>> 32) & 0xff)); + os.write((int)((v >>> 40) & 0xff)); + os.write((int)((v >>> 48) & 0xff)); + os.write((int)((v >>> 56) & 0xff)); + } + + /* + * Writes an array of bytes to the output stream. + */ + public static void writeBytes(OutputStream os, byte[] b) + throws IOException + { + os.write(b, 0, b.length); + } + + /* + * Writes an array of bytes to the output stream. + */ + public static void writeBytes(OutputStream os, byte[] b, int off, int len) + throws IOException + { + os.write(b, off, len); + } + + /* + * Append a slash at the end, if it does not have one yet + */ + public static byte[] toDirectoryPath(byte[] dir) { + if (dir.length != 0 && dir[dir.length - 1] != '/') { + dir = Arrays.copyOf(dir, dir.length + 1); + dir[dir.length - 1] = '/'; + } + return dir; + } + + /* + * Converts DOS time to Java time (number of milliseconds since epoch). + */ + public static long dosToJavaTime(long dtime) { + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), + (int)(((dtime >> 21) & 0x0f) - 1), + (int)((dtime >> 16) & 0x1f), + (int)((dtime >> 11) & 0x1f), + (int)((dtime >> 5) & 0x3f), + (int)((dtime << 1) & 0x3e)); + return d.getTime(); + } + + /* + * Converts Java time to DOS time. + */ + public static long javaToDosTime(long time) { + Date d = new Date(time); + int year = d.getYear() + 1900; + if (year < 1980) { + return (1 << 21) | (1 << 16); + } + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | + d.getSeconds() >> 1; + } + + private static final String regexMetaChars = ".^$+{[]|()"; + private static final String globMetaChars = "\\*?[{"; + private static boolean isRegexMeta(char c) { + return regexMetaChars.indexOf(c) != -1; + } + private static boolean isGlobMeta(char c) { + return globMetaChars.indexOf(c) != -1; + } + private static char EOL = 0; //TBD + private static char next(String glob, int i) { + if (i < glob.length()) { + return glob.charAt(i); + } + return EOL; + } + + /* + * Creates a regex pattern from the given glob expression. + * + * @throws PatternSyntaxException + */ + public static String toRegexPattern(String globPattern) { + boolean inGroup = false; + StringBuilder regex = new StringBuilder("^"); + + int i = 0; + while (i < globPattern.length()) { + char c = globPattern.charAt(i++); + switch (c) { + case '\\': + // escape special characters + if (i == globPattern.length()) { + throw new PatternSyntaxException("No character to escape", + globPattern, i - 1); + } + char next = globPattern.charAt(i++); + if (isGlobMeta(next) || isRegexMeta(next)) { + regex.append('\\'); + } + regex.append(next); + break; + case '/': + regex.append(c); + break; + case '[': + // don't match name separator in class + regex.append("[[^/]&&["); + if (next(globPattern, i) == '^') { + // escape the regex negation char if it appears + regex.append("\\^"); + i++; + } else { + // negation + if (next(globPattern, i) == '!') { + regex.append('^'); + i++; + } + // hyphen allowed at start + if (next(globPattern, i) == '-') { + regex.append('-'); + i++; + } + } + boolean hasRangeStart = false; + char last = 0; + while (i < globPattern.length()) { + c = globPattern.charAt(i++); + if (c == ']') { + break; + } + if (c == '/') { + throw new PatternSyntaxException("Explicit 'name separator' in class", + globPattern, i - 1); + } + // TBD: how to specify ']' in a class? + if (c == '\\' || c == '[' || + c == '&' && next(globPattern, i) == '&') { + // escape '\', '[' or "&&" for regex class + regex.append('\\'); + } + regex.append(c); + + if (c == '-') { + if (!hasRangeStart) { + throw new PatternSyntaxException("Invalid range", + globPattern, i - 1); + } + if ((c = next(globPattern, i++)) == EOL || c == ']') { + break; + } + if (c < last) { + throw new PatternSyntaxException("Invalid range", + globPattern, i - 3); + } + regex.append(c); + hasRangeStart = false; + } else { + hasRangeStart = true; + last = c; + } + } + if (c != ']') { + throw new PatternSyntaxException("Missing ']", globPattern, i - 1); + } + regex.append("]]"); + break; + case '{': + if (inGroup) { + throw new PatternSyntaxException("Cannot nest groups", + globPattern, i - 1); + } + regex.append("(?:(?:"); + inGroup = true; + break; + case '}': + if (inGroup) { + regex.append("))"); + inGroup = false; + } else { + regex.append('}'); + } + break; + case ',': + if (inGroup) { + regex.append(")|(?:"); + } else { + regex.append(','); + } + break; + case '*': + if (next(globPattern, i) == '*') { + // crosses directory boundaries + regex.append(".*"); + i++; + } else { + // within directory boundary + regex.append("[^/]*"); + } + break; + case '?': + regex.append("[^/]"); + break; + default: + if (isRegexMeta(c)) { + regex.append('\\'); + } + regex.append(c); + } + } + if (inGroup) { + throw new PatternSyntaxException("Missing '}", globPattern, i - 1); + } + return regex.append('$').toString(); + } +} diff --git a/jdk/test/demo/zipfs/Basic.java b/jdk/test/demo/zipfs/Basic.java new file mode 100644 index 00000000000..91f8af274ee --- /dev/null +++ b/jdk/test/demo/zipfs/Basic.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; +import java.util.*; +import java.net.URI; +import java.io.IOException; + +/** + * Basic test for zip provider + */ + +public class Basic { + public static void main(String[] args) throws Exception { + Path zipfile = Paths.get(args[0]); + + // Test: zip should should be returned in provider list + boolean found = false; + + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { + if (provider.getScheme().equalsIgnoreCase("zip")) { + found = true; + break; + } + } + if (!found) + throw new RuntimeException("'zip' provider not installed"); + + // Test: FileSystems#newFileSystem(FileRef) + Map env = new HashMap(); + FileSystems.newFileSystem(zipfile, env, null).close(); + + // Test: FileSystems#newFileSystem(URI) + URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4)); + FileSystem fs = FileSystems.newFileSystem(uri, env, null); + + // Test: exercise toUri method + String expected = uri.toString() + "#/foo"; + String actual = fs.getPath("/foo").toUri().toString(); + if (!actual.equals(expected)) { + throw new RuntimeException("toUri returned '" + actual + + "', expected '" + expected + "'"); + } + + // Test: exercise directory iterator and retrieval of basic attributes + Files.walkFileTree(fs.getPath("/"), new FileTreePrinter()); + + // Test: DirectoryStream + found = false; + DirectoryStream stream = fs.getPath("/").newDirectoryStream(); + try { + for (Path entry: stream) { + found = entry.toString().equals("/META-INF/"); + if (found) break; + } + } finally { + stream.close(); + } + + if (!found) + throw new RuntimeException("Expected file not found"); + + // Test: copy file from zip file to current (scratch) directory + Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider"); + if (source.exists()) { + Path target = Paths.get(source.getName().toString()); + source.copyTo(target, StandardCopyOption.REPLACE_EXISTING); + try { + long s1 = Attributes.readBasicFileAttributes(source).size(); + long s2 = Attributes.readBasicFileAttributes(target).size(); + if (s2 != s1) + throw new RuntimeException("target size != source size"); + } finally { + target.delete(); + } + } + + // Test: FileStore + FileStore store = fs.getPath("/").getFileStore(); + if (!store.supportsFileAttributeView("basic")) + throw new RuntimeException("BasicFileAttributeView should be supported"); + + // Test: ClosedFileSystemException + fs.close(); + if (fs.isOpen()) + throw new RuntimeException("FileSystem should be closed"); + try { + fs.getPath("/missing").checkAccess(AccessMode.READ); + } catch (ClosedFileSystemException x) { } + } + + // FileVisitor that pretty prints a file tree + static class FileTreePrinter extends SimpleFileVisitor { + private int indent = 0; + + private void indent() { + StringBuilder sb = new StringBuilder(indent); + for (int i=0; i %s", s, path); + } catch (Exception x) { + exc = x; + out.format("%s -> %s", s, x); + } + out.println(); + } + + Path path() { + return path; + } + + void fail() { + throw new RuntimeException("PathOps failed"); + } + + void checkPath() { + if (path == null) { + throw new InternalError("path is null"); + } + } + + void check(Object result, String expected) { + out.format("\tExpected: %s\n", expected); + out.format("\tActual: %s\n", result); + if (result == null) { + if (expected == null) return; + } else { + // compare string representations + if (expected != null && result.toString().equals(expected.toString())) + return; + } + fail(); + } + + void check(Object result, boolean expected) { + check(result, Boolean.toString(expected)); + } + + PathOps root(String expected) { + out.println("check root"); + checkPath(); + check(path.getRoot(), expected); + return this; + } + + PathOps parent(String expected) { + out.println("check parent"); + checkPath(); + check(path.getParent(), expected); + return this; + } + + PathOps name(String expected) { + out.println("check name"); + checkPath(); + check(path.getName(), expected); + return this; + } + + PathOps element(int index, String expected) { + out.format("check element %d\n", index); + checkPath(); + check(path.getName(index), expected); + return this; + } + + PathOps subpath(int startIndex, int endIndex, String expected) { + out.format("test subpath(%d,%d)\n", startIndex, endIndex); + checkPath(); + check(path.subpath(startIndex, endIndex), expected); + return this; + } + + PathOps starts(String prefix) { + out.format("test startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), true); + return this; + } + + PathOps notStarts(String prefix) { + out.format("test not startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), false); + return this; + } + + PathOps ends(String suffix) { + out.format("test endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), true); + return this; + } + + PathOps notEnds(String suffix) { + out.format("test not endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), false); + return this; + } + + PathOps absolute() { + out.println("check path is absolute"); + checkPath(); + check(path.isAbsolute(), true); + return this; + } + + PathOps notAbsolute() { + out.println("check path is not absolute"); + checkPath(); + check(path.isAbsolute(), false); + return this; + } + + PathOps resolve(String other, String expected) { + out.format("test resolve %s\n", other); + checkPath(); + check(path.resolve(other), expected); + return this; + } + + PathOps relativize(String other, String expected) { + out.format("test relativize %s\n", other); + checkPath(); + Path that = fs.getPath(other); + check(path.relativize(that), expected); + return this; + } + + PathOps normalize(String expected) { + out.println("check normalized path"); + checkPath(); + check(path.normalize(), expected); + return this; + } + + PathOps string(String expected) { + out.println("check string representation"); + checkPath(); + check(path, expected); + return this; + } + + PathOps invalid() { + if (!(exc instanceof InvalidPathException)) { + out.println("InvalidPathException not thrown as expected"); + fail(); + } + return this; + } + + static PathOps test(String s) { + return new PathOps(s); + } + + // -- PathOpss -- + + static void header(String s) { + out.println(); + out.println(); + out.println("-- " + s + " --"); + } + + static void doPathOpTests() { + header("Path operations"); + + // all components + test("/a/b/c") + .root("/") + .parent("/a/b") + .name("c"); + + // root component only + test("/") + .root("/") + .parent(null) + .name(null); + + // no root component + test("a/b") + .root(null) + .parent("a") + .name("b"); + + // name component only + test("foo") + .root(null) + .parent(null) + .name("foo"); + + // startsWith + test("/") + .starts("/") + .notStarts("/foo"); + test("/foo") + .starts("/") + .starts("/foo") + .notStarts("/f"); + test("/foo/bar") + .starts("/") + .starts("/foo") + .starts("/foo/bar") + .notStarts("/f") + .notStarts("foo") + .notStarts("foo/bar"); + test("foo") + .starts("foo") + .notStarts("f"); + test("foo/bar") + .starts("foo") + .starts("foo/bar") + .notStarts("f") + .notStarts("/foo") + .notStarts("/foo/bar"); + + // endsWith + test("/") + .ends("/") + .notEnds("foo") + .notEnds("/foo"); + test("/foo") + .ends("foo") + .ends("/foo") + .notEnds("/"); + test("/foo/bar") + .ends("bar") + .ends("foo/bar") + .ends("/foo/bar") + .notEnds("/bar"); + test("foo") + .ends("foo"); + test("foo/bar") + .ends("bar") + .ends("foo/bar"); + + // elements + test("a/b/c") + .element(0,"a") + .element(1,"b") + .element(2,"c"); + + // isAbsolute + test("/") + .absolute(); + test("/tmp") + .absolute(); + test("tmp") + .notAbsolute(); + + // resolve + test("/tmp") + .resolve("foo", "/tmp/foo") + .resolve("/foo", "/foo"); + test("tmp") + .resolve("foo", "tmp/foo") + .resolve("/foo", "/foo"); + + // relativize + test("/a/b/c") + .relativize("/a/b/c", null) + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/x", "../../x"); + + // normalize + test("/") + .normalize("/"); + test("foo") + .normalize("foo"); + test("/foo") + .normalize("/foo"); + test(".") + .normalize(null); + test("..") + .normalize(".."); + test("/..") + .normalize("/"); + test("/../..") + .normalize("/"); + test("foo/.") + .normalize("foo"); + test("./foo") + .normalize("foo"); + test("foo/..") + .normalize(null); + test("../foo") + .normalize("../foo"); + test("../../foo") + .normalize("../../foo"); + test("foo/bar/..") + .normalize("foo"); + test("foo/bar/gus/../..") + .normalize("foo"); + test("/foo/bar/gus/../..") + .normalize("/foo"); + + // invalid + test("foo\u0000bar") + .invalid(); + test("\u0000foo") + .invalid(); + test("bar\u0000") + .invalid(); + test("//foo\u0000bar") + .invalid(); + test("//\u0000foo") + .invalid(); + test("//bar\u0000") + .invalid(); + + // normalization + test("//foo//bar") + .string("/foo/bar") + .root("/") + .parent("/foo") + .name("bar"); + } + + static void npes() { + header("NullPointerException"); + + Path path = fs.getPath("foo"); + + try { + path.resolve((String)null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.relativize(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.compareTo(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.startsWith(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.endsWith(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + } + + public static void main(String[] args) throws Throwable { + + Path zipfile = Paths.get(args[0]); + Map env = new HashMap(); + fs = FileSystems.newFileSystem(zipfile, env, null); + npes(); + doPathOpTests(); + fs.close(); + } +} diff --git a/jdk/test/demo/zipfs/ZipFSTester.java b/jdk/test/demo/zipfs/ZipFSTester.java new file mode 100644 index 00000000000..54b9274db13 --- /dev/null +++ b/jdk/test/demo/zipfs/ZipFSTester.java @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.util.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * Tests various zipfs operations. + */ + +public class ZipFSTester { + + public static void main(String[] args) throws Throwable { + FileSystem fs = null; + try { + fs = newZipFileSystem(Paths.get(args[0]), new HashMap()); + test(fs); + test2(fs); // more tests + } finally { + if (fs != null) + fs.close(); + } + } + + static void test(FileSystem fs) + throws Exception + { + Random rdm = new Random(); + + // clone a fs and test on it + Path tmpfsPath = getTempPath(); + Map env = new HashMap(); + env.put("createNew", true); + FileSystem fs0 = newZipFileSystem(tmpfsPath, env); + z2zcopy(fs, fs0, "/", 0); + fs0.close(); // sync to file + + fs = newZipFileSystem(tmpfsPath, new HashMap()); + + try { + // prepare a src + Path src = getTempPath(); + String tmpName = src.toString(); + OutputStream os = src.newOutputStream(); + byte[] bits = new byte[12345]; + rdm.nextBytes(bits); + os.write(bits); + os.close(); + + // copyin + Path dst = getPathWithParents(fs, tmpName); + src.copyTo(dst); + checkEqual(src, dst); + + // copy + Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + + "/efg" + rdm.nextInt(100) + "/foo.class"); + dst.copyTo(dst2); + //dst.moveTo(dst2); + checkEqual(src, dst2); + + // delete + dst.delete(); + if (dst.exists()) + throw new RuntimeException("Failed!"); + + // moveout + Path dst3 = Paths.get(tmpName + "_Tmp"); + dst2.moveTo(dst3); + checkEqual(src, dst3); + + // delete + if (dst2.exists()) + throw new RuntimeException("Failed!"); + dst3.delete(); + if (dst3.exists()) + throw new RuntimeException("Failed!"); + + // newInputStream on dir + Path parent = dst2.getParent(); + try { + parent.newInputStream(); + throw new RuntimeException("Failed"); + } catch (FileSystemException e) { + e.printStackTrace(); // expected fse + } + + // rmdirs + try { + rmdirs(parent); + } catch (IOException x) { + x.printStackTrace(); + } + + // newFileChannel() copy in, out and verify via fch + fchCopy(src, dst); // in + checkEqual(src, dst); + Path tmp = Paths.get(tmpName + "_Tmp"); + fchCopy(dst, tmp); // out + checkEqual(src, tmp); + tmp.delete(); + + // test channels + channel(fs, dst); + dst.delete(); + src.delete(); + } finally { + if (fs != null) + fs.close(); + if (tmpfsPath.exists()) + tmpfsPath.delete(); + } + } + + static void test2(FileSystem fs) throws Exception { + + Path fs1Path = getTempPath(); + Path fs2Path = getTempPath(); + Path fs3Path = getTempPath(); + + if (fs1Path.exists()) + fs1Path.delete(); + if (fs2Path.exists()) + fs2Path.delete(); + if (fs3Path.exists()) + fs3Path.delete(); + + // create a new filesystem, copy everything from fs + Map env = new HashMap(); + env.put("createNew", true); + FileSystem fs0 = newZipFileSystem(fs1Path, env); + + final FileSystem fs2 = newZipFileSystem(fs2Path, env); + final FileSystem fs3 = newZipFileSystem(fs3Path, env); + + System.out.println("copy src: fs -> fs0..."); + z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 + fs0.close(); // dump to file + + System.out.println("open fs0 as fs1"); + env = new HashMap(); + final FileSystem fs1 = newZipFileSystem(fs1Path, env); + + System.out.println("listing..."); + final ArrayList files = new ArrayList<>(); + final ArrayList dirs = new ArrayList<>(); + list(fs1.getPath("/"), files, dirs); + + Thread t0 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 0); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t1 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 1); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 2); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t3 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(files); + Collections.shuffle(list); + while (!list.isEmpty()) { + Iterator itr = list.iterator(); + while (itr.hasNext()) { + String path = itr.next(); + try { + if (fs2.getPath(path).exists()) { + z2zmove(fs2, fs3, path); + itr.remove(); + } + } catch (FileAlreadyExistsException x){ + itr.remove(); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + } + + }); + + System.out.println("copying/removing..."); + t0.start(); t1.start(); t2.start(); t3.start(); + t0.join(); t1.join(); t2.join(); t3.join(); + + System.out.println("closing: fs1, fs2"); + fs1.close(); + fs2.close(); + + int failed = 0; + System.out.println("checkEqual: fs vs fs3"); + for (String path : files) { + try { + checkEqual(fs.getPath(path), fs3.getPath(path)); + } catch (IOException x) { + //x.printStackTrace(); + failed++; + } + } + System.out.println("closing: fs3"); + fs3.close(); + + System.out.println("opening: fs3 as fs4"); + FileSystem fs4 = newZipFileSystem(fs3Path, env); + + + ArrayList files2 = new ArrayList<>(); + ArrayList dirs2 = new ArrayList<>(); + list(fs4.getPath("/"), files2, dirs2); + + System.out.println("checkEqual: fs vs fs4"); + for (String path : files2) { + checkEqual(fs.getPath(path), fs4.getPath(path)); + } + System.out.println("walking: fs4"); + walk(fs4.getPath("/")); + System.out.println("closing: fs4"); + fs4.close(); + + System.out.printf("failed=%d%n", failed); + + fs1Path.delete(); + fs2Path.delete(); + fs3Path.delete(); + } + + private static FileSystem newZipFileSystem(Path path, Map env) + throws IOException + { + return FileSystems.newFileSystem( + URI.create("zip" + + path.toUri().toString().substring(4)), + env, + null); + } + + private static Path getTempPath() throws IOException + { + File tmp = File.createTempFile("testzipfs_", "zip"); + tmp.delete(); // we need a clean path, no file + return tmp.toPath(); + } + + private static void list(Path path, List files, List dirs ) + throws IOException + { + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream ds = path.newDirectoryStream(); + for (Path child : ds) + list(child, files, dirs); + ds.close(); + dirs.add(path.toString()); + } else { + files.add(path.toString()); + } + } + + private static void z2zcopy(FileSystem src, FileSystem dst, String path, + int method) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName(), + method); + } + ds.close(); + } else { + try { + if (dstPath.exists()) + return; + switch (method) { + case 0: + srcPath.copyTo(dstPath); + break; + case 1: + chCopy(srcPath, dstPath); + break; + case 2: + //fchCopy(srcPath, dstPath); + streamCopy(srcPath, dstPath); + break; + } + } catch (FileAlreadyExistsException x) {} + } + } + + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) + mkdirs(dstPath); + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zmove(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName()); + } + ds.close(); + } else { + //System.out.println("moving..." + path); + Path parent = dstPath.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + srcPath.moveTo(dstPath); + } + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void mkdirs(Path path) throws IOException { + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (parent.notExists()) + mkdirs(parent); + } + path.createDirectory(); + } + + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + path.delete(); + path = path.getParent(); + } + } + + // check the content of two paths are equal + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + InputStream isSrc = src.newInputStream(); + InputStream isDst = dst.newInputStream(); + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + + try { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } finally { + isSrc.close(); + isDst.close(); + } + + // channels + SeekableByteChannel chSrc = src.newByteChannel(); + SeekableByteChannel chDst = dst.newByteChannel(); + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + try { + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + } catch (IOException x) { + x.printStackTrace(); + } finally { + chSrc.close(); + chDst.close(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + FileChannel srcFc = src.getFileSystem() + .provider() + .newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem() + .provider() + .newFileChannel(dst, openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } finally { + srcFc.close(); + dstFc.close(); + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + SeekableByteChannel srcCh = src.newByteChannel(read); + SeekableByteChannel dstCh = dst.newByteChannel(openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + } finally { + srcCh.close(); + dstCh.close(); + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + InputStream isSrc = src.newInputStream(); + OutputStream osDst = dst.newOutputStream(); + byte[] buf = new byte[8192]; + try { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } finally { + isSrc.close(); + osDst.close(); + } + } + + static void channel(FileSystem fs, Path path) + throws Exception + { + System.out.println("test ByteChannel..."); + SeekableByteChannel sbc = path.newByteChannel(); + Set read = new HashSet<>(); + read.add(READ); + System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size()); + ByteBuffer bb = ByteBuffer.allocate((int)sbc.size()); + int n = sbc.read(bb); + System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size()); + int N = 120; + sbc.close(); + + // sbc.position(pos) is not supported in current version + // try the FileChannel + sbc = fs.provider().newFileChannel(path, read); + sbc.position(N); + System.out.printf(" sbc[2]: pos=%d, size=%d%n", + sbc.position(), sbc.size()); + bb2.limit(100); + n = sbc.read(bb2); + System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n", + N, bb.get(N) & 0xff, bb2.get(0) & 0xff); + sbc.close(); + } + + // create parents if does not exist + static Path getPathWithParents(FileSystem fs, String name) + throws Exception + { + Path path = fs.getPath(name); + Path parent = path.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + return path; + } +} diff --git a/jdk/test/demo/zipfs/basic.sh b/jdk/test/demo/zipfs/basic.sh new file mode 100644 index 00000000000..c6cfb77caf3 --- /dev/null +++ b/jdk/test/demo/zipfs/basic.sh @@ -0,0 +1,73 @@ +# +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# @test +# @bug 6990846 +# @summary Test ZipFileSystem demo +# @build Basic PathOps ZipFSTester +# @run shell basic.sh + +if [ -z "${TESTJAVA}" ]; then + echo "Test must be run with jtreg" + exit 0 +fi + +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar" +if [ ! -r "${ZIPFS}" ]; then + echo "${ZIPFS} not found" + exit 0 +fi + +OS=`uname -s` +case "$OS" in + Windows_* ) + CLASSPATH="${TESTCLASSES};${ZIPFS}" + ;; + * ) + CLASSPATH="${TESTCLASSES}:${ZIPFS}" + ;; +esac +export CLASSPATH + +failures=0 + +go() { + echo "" + ${TESTJAVA}/bin/java $1 $2 $3 2>&1 + if [ $? != 0 ]; then failures=`expr $failures + 1`; fi +} + +# Run the tests + +go Basic "${ZIPFS}" +go PathOps "${ZIPFS}" +go ZipFSTester "${ZIPFS}" + +# +# Results +# + +if [ $failures -gt 0 ]; +then echo "$failures tests failed"; +else echo "All tests passed"; +fi +exit $failures From d64d53d932098961346bf7ccc2ded70935270f58 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 17:23:19 +0200 Subject: [PATCH 87/88] Added tag jdk7-b112 for changeset f960f117f162 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 5cfc1c804be..6a29a55b9a1 100644 --- a/.hgtags +++ b/.hgtags @@ -86,3 +86,4 @@ c4c8a5bc54f66abc68cd185d9294042121922154 jdk7-b99 e02b4d709e177d08d56130a4bc68061e4bbacc7d jdk7-b109 a6442d6bc38a44152e0662688213ce4d2701f42a jdk7-b110 69f3edf083477955b5bd2f754252c7504167d8e1 jdk7-b111 +f960f117f1623629f64203e2b09a92a8f6f14ff5 jdk7-b112 From 056918b32719845f70e6b45b711fa7a119ef3bfd Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 17:23:40 +0200 Subject: [PATCH 88/88] Added tag jdk7-b113 for changeset 1fee41c7ed2b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 6a29a55b9a1..c3213062fb5 100644 --- a/.hgtags +++ b/.hgtags @@ -87,3 +87,4 @@ e02b4d709e177d08d56130a4bc68061e4bbacc7d jdk7-b109 a6442d6bc38a44152e0662688213ce4d2701f42a jdk7-b110 69f3edf083477955b5bd2f754252c7504167d8e1 jdk7-b111 f960f117f1623629f64203e2b09a92a8f6f14ff5 jdk7-b112 +1fee41c7ed2b3388970a756a85aa693c0de8407a jdk7-b113