OpenJDK / aarch32-port / jdk9 / jdk
changeset 5941:61ddb3fd000a jdk8-b61
Merge
author | lana |
---|---|
date | Thu, 11 Oct 2012 16:59:50 -0700 |
parents | 869519bc17ce d8581143e11d |
children | 1ae6420126af a0a2b186ae28 117eed515e42 34d502d14a61 e23f8e0a1d89 |
files | src/share/classes/sun/util/xml/XMLUtils.java src/share/test/pack200/pack.conf |
diffstat | 200 files changed, 57985 insertions(+), 1755 deletions(-) [+] |
line wrap: on
line diff
--- a/make/java/java/FILES_java.gmk Thu Oct 11 09:50:14 2012 -0700 +++ b/make/java/java/FILES_java.gmk Thu Oct 11 16:59:50 2012 -0700 @@ -213,6 +213,7 @@ sun/util/locale/provider/DateFormatSymbolsProviderImpl.java \ sun/util/locale/provider/DecimalFormatSymbolsProviderImpl.java \ sun/util/locale/provider/DictionaryBasedBreakIterator.java \ + sun/util/locale/provider/FallbackLocaleProviderAdapter.java \ sun/util/locale/provider/HostLocaleProviderAdapter.java \ sun/util/locale/provider/HostLocaleProviderAdapterImpl.java \ sun/util/locale/provider/JRELocaleConstants.java \ @@ -235,6 +236,7 @@ java/util/Observer.java \ java/util/Properties.java \ java/util/InvalidPropertiesFormatException.java \ + sun/util/spi/XmlPropertiesProvider.java \ java/util/PropertyPermission.java \ java/util/PropertyResourceBundle.java \ java/util/Random.java \
--- a/make/java/nio/mapfile-bsd Thu Oct 11 09:50:14 2012 -0700 +++ b/make/java/nio/mapfile-bsd Thu Oct 11 16:59:50 2012 -0700 @@ -108,6 +108,7 @@ Java_sun_nio_ch_Net_setInterface6; Java_sun_nio_ch_Net_getInterface6; Java_sun_nio_ch_Net_shutdown; + Java_sun_nio_ch_Net_poll; Java_sun_nio_ch_PollArrayWrapper_interrupt; Java_sun_nio_ch_PollArrayWrapper_poll0; Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
--- a/make/java/nio/mapfile-linux Thu Oct 11 09:50:14 2012 -0700 +++ b/make/java/nio/mapfile-linux Thu Oct 11 16:59:50 2012 -0700 @@ -116,6 +116,7 @@ Java_sun_nio_ch_Net_setInterface6; Java_sun_nio_ch_Net_getInterface6; Java_sun_nio_ch_Net_shutdown; + Java_sun_nio_ch_Net_poll; Java_sun_nio_ch_PollArrayWrapper_interrupt; Java_sun_nio_ch_PollArrayWrapper_poll0; Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
--- a/make/java/nio/mapfile-solaris Thu Oct 11 09:50:14 2012 -0700 +++ b/make/java/nio/mapfile-solaris Thu Oct 11 16:59:50 2012 -0700 @@ -104,6 +104,7 @@ Java_sun_nio_ch_Net_setInterface6; Java_sun_nio_ch_Net_getInterface6; Java_sun_nio_ch_Net_shutdown; + Java_sun_nio_ch_Net_poll; Java_sun_nio_ch_PollArrayWrapper_interrupt; Java_sun_nio_ch_PollArrayWrapper_poll0; Java_sun_nio_ch_ServerSocketChannelImpl_accept0;
--- a/make/javax/crypto/Makefile Thu Oct 11 09:50:14 2012 -0700 +++ b/make/javax/crypto/Makefile Thu Oct 11 16:59:50 2012 -0700 @@ -158,7 +158,12 @@ # ifdef OPENJDK -all: build-jar install-jar build-policy install-limited +ifdef UNLIMITED_CRYPTO +POLICY = install-unlimited +else +POLICY = install-limited +endif +all: build-jar install-jar build-policy $(POLICY) else # OPENJDK ifeq ($(strip $(FILES_java)),) all:
--- a/make/sun/osxapp/Makefile Thu Oct 11 09:50:14 2012 -0700 +++ b/make/sun/osxapp/Makefile Thu Oct 11 16:59:50 2012 -0700 @@ -28,6 +28,11 @@ PRODUCT = sun include $(BUILDDIR)/common/Defs.gmk +GEN_DIR=$(GENSRCDIR)/sun/osxapp +ICON_DATA = $(GEN_DIR)/AWTIconData.h + +CLASSES_INIT += $(ICON_DATA) + # # Files # @@ -63,6 +68,7 @@ -framework QuartzCore CPPFLAGS += \ + -I$(GEN_DIR) \ $(call NativeSrcDirList,-I,/native/sun/osxapp) @@ -70,6 +76,34 @@ CPPFLAGS += -DINTERNAL_BUILD endif -clean clobber:: +TEMPDIR_CLASSES = $(TEMPDIR)/classes -.PHONY: +$(TEMPDIR_CLASSES)/sun/osxapp/ToBin.class: ToBin.java + @$(prep-target) + $(BOOT_JAVAC_CMD) -d $(TEMPDIR_CLASSES) $< + +ifdef OPENJDK + ICONS_PATH_PREFIX=$(PLATFORM_SRC_MACOS) +else + ICONS_PATH_PREFIX=$(CLOSED_SRC)/macosx +endif + +generated.clean: + $(RM) -r $(GEN_DIR)/*.h + +ICONPATH=$(ICONS_PATH_PREFIX)/native/sun/osxapp/resource/icons +ICON = $(ICONPATH)/JavaApp.icns + +$(GEN_DIR)/AWTIconData.h: $(TEMPDIR_CLASSES)/sun/osxapp/ToBin.class $(ICON) + $(prep-target) + $(RM) $(ICON_DATA) + $(ECHO) "static unsigned char sAWTIconData[] = { " >> $(ICON_DATA); \ + $(CAT) $(ICON) | \ + $(BOOT_JAVA_CMD) -cp $(TEMPDIR_CLASSES) -Djava.awt.headless=true \ + sun.osxapp.ToBin >> $(ICON_DATA); \ + $(ECHO) "};" >> $(ICON_DATA); + + +clean clobber:: generated.clean + +.PHONY: generated.clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/sun/osxapp/ToBin.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, 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 sun.osxapp; + +import java.io.*; + +public class ToBin { + public static void main(String[] args) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[4096]; + + while ((nRead = System.in.read(data, 0, data.length)) != -1) { + baos.write(data, 0, nRead); + } + + baos.flush(); + + byte[] buf = baos.toByteArray(); + for (int i = 0; i < buf.length; i++) { + System.out.print(String.format("0x%1$02X", buf[i]) + ", "); + if (i % 20 == 0) { + System.out.println(); + } + } + } +}
--- a/make/sun/util/Makefile Thu Oct 11 09:50:14 2012 -0700 +++ b/make/sun/util/Makefile Thu Oct 11 16:59:50 2012 -0700 @@ -41,3 +41,20 @@ # include $(BUILDDIR)/common/Classes.gmk +# +# Rules for XML properties provider configuration file +# +SERVICEDIR = $(CLASSBINDIR)/META-INF/services +FILES_copy = $(SERVICEDIR)/sun.util.spi.XmlPropertiesProvider + +copy-files: $(FILES_copy) + +$(SERVICEDIR)/%: $(SHARE_SRC)/classes/sun/util/xml/META-INF/services/% + $(install-file) + +build: copy-files + +clean:: + $(RM) $(FILES_copy) + +
--- a/src/macosx/classes/sun/lwawt/LWCanvasPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWCanvasPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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,26 +26,27 @@ package sun.lwawt; +import java.awt.AWTException; import java.awt.BufferCapabilities; -import java.awt.Canvas; import java.awt.Component; +import java.awt.Dimension; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.peer.CanvasPeer; import javax.swing.JComponent; -final class LWCanvasPeer extends LWComponentPeer<Component, JComponent> - implements CanvasPeer { +class LWCanvasPeer<T extends Component, D extends JComponent> + extends LWComponentPeer<T, D> implements CanvasPeer { - LWCanvasPeer(final Canvas target, PlatformComponent platformComponent) { + LWCanvasPeer(final T target, final PlatformComponent platformComponent) { super(target, platformComponent); } - // ---- PEER METHODS ---- // @Override - public void createBuffers(int numBuffers, BufferCapabilities caps) { + public void createBuffers(int numBuffers, BufferCapabilities caps) + throws AWTException { // TODO } @@ -67,10 +68,20 @@ } @Override - public GraphicsConfiguration getAppropriateGraphicsConfiguration( + public final GraphicsConfiguration getAppropriateGraphicsConfiguration( GraphicsConfiguration gc) { // TODO return gc; } + + @Override + public final Dimension getPreferredSize() { + return getMinimumSize(); + } + + @Override + public final Dimension getMinimumSize() { + return getBounds().getSize(); + } }
--- a/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -186,6 +186,11 @@ } @Override + public Dimension getPreferredSize() { + return getCurrentButton().getPreferredSize(); + } + + @Override @Transient public Dimension getMinimumSize() { return getCurrentButton().getMinimumSize();
--- a/src/macosx/classes/sun/lwawt/LWComponentPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWComponentPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -123,7 +123,7 @@ // private volatile boolean paintPending; private volatile boolean isLayouting; - private D delegate = null; + private final D delegate; private Container delegateContainer; private Component delegateDropTarget; private final Object dropTargetLock = new Object(); @@ -133,6 +133,11 @@ private final PlatformComponent platformComponent; + /** + * Character with reasonable value between the minimum width and maximum. + */ + static final char WIDE_CHAR = '0'; + private final class DelegateContainer extends Container { { enableEvents(0xFFFFFFFF); @@ -267,9 +272,7 @@ } protected final D getDelegate() { - synchronized (getStateLock()) { - return delegate; - } + return delegate; } protected Component getDelegateFocusOwner() { @@ -698,26 +701,23 @@ } @Override - public FontMetrics getFontMetrics(Font f) { + public FontMetrics getFontMetrics(final Font f) { // Borrow the metrics from the top-level window // return getWindowPeer().getFontMetrics(f); // Obtain the metrics from the offscreen window where this peer is // mostly drawn to. // TODO: check for "use platform metrics" settings - Graphics g = getWindowPeer().getGraphics(); - try { - if (g != null) { + final Graphics g = getOnscreenGraphics(); + if (g != null) { + try { return g.getFontMetrics(f); - } else { - synchronized (getDelegateLock()) { - return delegateContainer.getFontMetrics(f); - } - } - } finally { - if (g != null) { + } finally { g.dispose(); } } + synchronized (getDelegateLock()) { + return delegateContainer.getFontMetrics(f); + } } @Override @@ -847,31 +847,46 @@ } /** - * Should be overridden in subclasses to forward the request - * to the Swing helper component, if required. + * Determines the preferred size of the component. By default forwards the + * request to the Swing helper component. Should be overridden in subclasses + * if required. */ @Override public Dimension getPreferredSize() { - // It looks like a default implementation for all toolkits - return getMinimumSize(); + final Dimension size; + synchronized (getDelegateLock()) { + size = getDelegate().getPreferredSize(); + } + return validateSize(size); } - /* - * Should be overridden in subclasses to forward the request - * to the Swing helper component. + /** + * Determines the minimum size of the component. By default forwards the + * request to the Swing helper component. Should be overridden in subclasses + * if required. */ @Override public Dimension getMinimumSize() { - D delegate = getDelegate(); + final Dimension size; + synchronized (getDelegateLock()) { + size = getDelegate().getMinimumSize(); + } + return validateSize(size); + } - if (delegate == null) { - // Is it a correct default value? - return getBounds().getSize(); - } else { - synchronized (getDelegateLock()) { - return delegate.getMinimumSize(); - } + /** + * In some situations delegates can return empty minimum/preferred size. + * (For example: empty JLabel, etc), but awt components never should be + * empty. In the XPeers or WPeers we use some magic constants, but here we + * try to use something more useful, + */ + private Dimension validateSize(final Dimension size) { + if (size.width == 0 || size.height == 0) { + final FontMetrics fm = getFontMetrics(getFont()); + size.width = fm.charWidth(WIDE_CHAR); + size.height = fm.getHeight(); } + return size; } @Override
--- a/src/macosx/classes/sun/lwawt/LWContainerPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWContainerPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -41,7 +41,7 @@ import javax.swing.JComponent; abstract class LWContainerPeer<T extends Container, D extends JComponent> - extends LWComponentPeer<T, D> + extends LWCanvasPeer<T, D> implements ContainerPeer { // List of child peers sorted by z-order from bottom-most
--- a/src/macosx/classes/sun/lwawt/LWLabelPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWLabelPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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,37 +26,26 @@ package sun.lwawt; -import java.awt.Dimension; -import java.awt.FontMetrics; import java.awt.Label; import java.awt.peer.LabelPeer; import javax.swing.JLabel; import javax.swing.SwingConstants; -import javax.tools.annotation.GenerateNativeHeader; - /** * Lightweight implementation of {@link LabelPeer}. Delegates most of the work * to the {@link JLabel}. */ -/* No native methods here, but the constants are needed in the supporting JNI code */ -@GenerateNativeHeader final class LWLabelPeer extends LWComponentPeer<Label, JLabel> implements LabelPeer { - private static final int TEXT_XPAD = 5; - private static final int TEXT_YPAD = 1; - LWLabelPeer(final Label target, final PlatformComponent platformComponent) { super(target, platformComponent); } @Override protected JLabel createDelegate() { - final JLabel label = new JLabel(); - label.setVerticalAlignment(SwingConstants.TOP); - return label; + return new JLabel(); } @Override @@ -80,24 +69,6 @@ } } - @Override - public Dimension getMinimumSize() { - int w = TEXT_XPAD; - int h = TEXT_YPAD; - final FontMetrics fm = getFontMetrics(getFont()); - if (fm != null) { - final String text; - synchronized (getDelegateLock()) { - text = getDelegate().getText(); - } - if (text != null) { - w += fm.stringWidth(text); - } - h += fm.getHeight(); - } - return new Dimension(w, h); - } - /** * Converts {@code Label} alignment constant to the {@code JLabel} constant. * If wrong Label alignment provided returns default alignment.
--- a/src/macosx/classes/sun/lwawt/LWListPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWListPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -32,10 +32,22 @@ import java.awt.peer.ListPeer; import java.util.Arrays; -final class LWListPeer - extends LWComponentPeer<List, LWListPeer.ScrollableJList> +/** + * Lightweight implementation of {@link ListPeer}. + */ +final class LWListPeer extends LWComponentPeer<List, LWListPeer.ScrollableJList> implements ListPeer { + /** + * The default number of visible rows. + */ + private static final int DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List, + + /** + * This text is used for cell bounds calculation. + */ + private static final String TEXT = "0123456789abcde"; + LWListPeer(final List target, final PlatformComponent platformComponent) { super(target, platformComponent); if (!getTarget().isBackgroundSet()) { @@ -135,6 +147,16 @@ } @Override + public Dimension getPreferredSize() { + return getMinimumSize(); + } + + @Override + public Dimension getMinimumSize() { + return getMinimumSize(DEFAULT_VISIBLE_ROWS); + } + + @Override public Dimension getPreferredSize(final int rows) { return getMinimumSize(rows); } @@ -142,16 +164,26 @@ @Override public Dimension getMinimumSize(final int rows) { synchronized (getDelegateLock()) { - final int margin = 2; - final int space = 1; + final Dimension size = getCellSize(); + size.height *= rows; + // Always take vertical scrollbar into account. + final JScrollBar vbar = getDelegate().getVerticalScrollBar(); + size.width += vbar != null ? vbar.getMinimumSize().width : 0; + // JScrollPane and JList insets + final Insets pi = getDelegate().getInsets(); + final Insets vi = getDelegate().getView().getInsets(); + size.width += pi.left + pi.right + vi.left + vi.right; + size.height += pi.top + pi.bottom + vi.top + vi.bottom; + return size; + } + } - // TODO: count ScrollPane's scrolling elements if any. - final FontMetrics fm = getFontMetrics(getFont()); - final int itemHeight = (fm.getHeight() - fm.getLeading()) + (2 * space); - - return new Dimension(20 + (fm == null ? 10 * 15 : fm.stringWidth("0123456789abcde")), - (fm == null ? 10 : itemHeight) * rows + (2 * margin)); - } + private Dimension getCellSize() { + final JList<String> jList = getDelegate().getView(); + final ListCellRenderer<? super String> cr = jList.getCellRenderer(); + final Component cell = cr.getListCellRendererComponent(jList, TEXT, 0, + false, false); + return cell.getPreferredSize(); } private void revalidate() { @@ -165,10 +197,10 @@ private boolean skipStateChangedEvent; - private DefaultListModel<Object> model = - new DefaultListModel<Object>() { + private final DefaultListModel<String> model = + new DefaultListModel<String>() { @Override - public void add(final int index, final Object element) { + public void add(final int index, final String element) { if (index == -1) { addElement(element); } else { @@ -181,7 +213,7 @@ ScrollableJList() { getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); - final JList<Object> list = new JListDelegate(); + final JList<String> list = new JListDelegate(); list.addListSelectionListener(this); getViewport().setView(list); @@ -223,11 +255,11 @@ } } - public JList getView() { - return (JList) getViewport().getView(); + public JList<String> getView() { + return (JList<String>) getViewport().getView(); } - public DefaultListModel<Object> getModel() { + public DefaultListModel<String> getModel() { return model; } @@ -254,7 +286,7 @@ } } - private final class JListDelegate extends JList<Object> { + private final class JListDelegate extends JList<String> { JListDelegate() { super(ScrollableJList.this.model); @@ -272,7 +304,7 @@ final int index = locationToIndex(e.getPoint()); if (0 <= index && index < getModel().getSize()) { LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED, - getModel().getElementAt(index).toString(), e.getWhen(), e.getModifiers())); + getModel().getElementAt(index), e.getWhen(), e.getModifiers())); } } } @@ -281,10 +313,10 @@ protected void processKeyEvent(final KeyEvent e) { super.processKeyEvent(e); if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ENTER) { - final Object selectedValue = getSelectedValue(); + final String selectedValue = getSelectedValue(); if(selectedValue != null){ LWListPeer.this.postEvent(new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED, - selectedValue.toString(), e.getWhen(), e.getModifiers())); + selectedValue, e.getWhen(), e.getModifiers())); } } }
--- a/src/macosx/classes/sun/lwawt/LWPanelPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWPanelPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -26,7 +26,6 @@ package sun.lwawt; -import java.awt.Dimension; import java.awt.Panel; import java.awt.peer.PanelPeer; @@ -43,9 +42,4 @@ public JPanel createDelegate() { return new JPanel(); } - - @Override - public Dimension getMinimumSize() { - return getBounds().getSize(); - } }
--- a/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -27,7 +27,6 @@ package sun.lwawt; import java.awt.Adjustable; -import java.awt.Dimension; import java.awt.Scrollbar; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; @@ -93,13 +92,6 @@ } } - @Override - public Dimension getPreferredSize() { - synchronized (getDelegateLock()) { - return getDelegate().getPreferredSize(); - } - } - // Peer also registered as a listener for ComponentDelegate component @Override public void adjustmentValueChanged(final AdjustmentEvent e) {
--- a/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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,6 +29,7 @@ import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; +import java.awt.Insets; import java.awt.Point; import java.awt.TextArea; import java.awt.event.TextEvent; @@ -41,11 +42,22 @@ import javax.swing.text.Document; import javax.swing.text.JTextComponent; +/** + * Lightweight implementation of {@link TextAreaPeer}. Delegates most of the + * work to the {@link JTextArea} inside JScrollPane. + */ final class LWTextAreaPeer extends LWTextComponentPeer<TextArea, LWTextAreaPeer.ScrollableJTextArea> implements TextAreaPeer { + /** + * The default number of visible columns. + */ private static final int DEFAULT_COLUMNS = 60; + + /** + * The default number of visible rows. + */ private static final int DEFAULT_ROWS = 10; LWTextAreaPeer(final TextArea target, @@ -87,26 +99,41 @@ } @Override + public Dimension getPreferredSize() { + return getMinimumSize(); + } + + @Override public Dimension getMinimumSize() { return getMinimumSize(DEFAULT_ROWS, DEFAULT_COLUMNS); } @Override - public Dimension getMinimumSize(final int rows, final int columns) { - return getPreferredSize(rows, columns); + public Dimension getPreferredSize(final int rows, final int columns) { + return getMinimumSize(rows, columns); } @Override - public Dimension getPreferredSize(final int rows, final int columns) { - final Dimension size = super.getPreferredSize(rows, columns); + public Dimension getMinimumSize(final int rows, final int columns) { + final Dimension size = super.getMinimumSize(rows, columns); synchronized (getDelegateLock()) { - final JScrollBar vbar = getDelegate().getVerticalScrollBar(); - final JScrollBar hbar = getDelegate().getHorizontalScrollBar(); - final int scrollbarW = vbar != null ? vbar.getWidth() : 0; - final int scrollbarH = hbar != null ? hbar.getHeight() : 0; - return new Dimension(size.width + scrollbarW, - size.height + scrollbarH); + // JScrollPane insets + final Insets pi = getDelegate().getInsets(); + size.width += pi.left + pi.right; + size.height += pi.top + pi.bottom; + // Take scrollbars into account. + final int vsbPolicy = getDelegate().getVerticalScrollBarPolicy(); + if (vsbPolicy == ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) { + final JScrollBar vbar = getDelegate().getVerticalScrollBar(); + size.width += vbar != null ? vbar.getMinimumSize().width : 0; + } + final int hsbPolicy = getDelegate().getHorizontalScrollBarPolicy(); + if (hsbPolicy == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS) { + final JScrollBar hbar = getDelegate().getHorizontalScrollBar(); + size.height += hbar != null ? hbar.getMinimumSize().height : 0; + } } + return size; } @Override
--- a/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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,10 +48,7 @@ extends LWComponentPeer<T, D> implements DocumentListener, TextComponentPeer, InputMethodListener { - /** - * Character with reasonable value between the minimum width and maximum. - */ - protected static final char WIDE_CHAR = 'w'; + private volatile boolean firstChangeSkipped; LWTextComponentPeer(final T target, @@ -95,18 +92,16 @@ */ abstract JTextComponent getTextComponent(); - public Dimension getPreferredSize(final int rows, final int columns) { + public Dimension getMinimumSize(final int rows, final int columns) { final Insets insets; synchronized (getDelegateLock()) { - insets = getDelegate().getInsets(); + insets = getTextComponent().getInsets(); } final int borderHeight = insets.top + insets.bottom; final int borderWidth = insets.left + insets.right; final FontMetrics fm = getFontMetrics(getFont()); - final int charWidth = (fm != null) ? fm.charWidth(WIDE_CHAR) : 10; - final int itemHeight = (fm != null) ? fm.getHeight() : 10; - return new Dimension(columns * charWidth + borderWidth, - rows * itemHeight + borderHeight); + return new Dimension(fm.charWidth(WIDE_CHAR) * columns + borderWidth, + fm.getHeight() * rows + borderHeight); } @Override @@ -187,6 +182,7 @@ } } + //TODO IN XAWT we just return true.. @Override public final boolean isFocusable() { return getTarget().isFocusable();
--- a/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -37,16 +37,10 @@ import javax.swing.JPasswordField; import javax.swing.text.JTextComponent; -import javax.tools.annotation.GenerateNativeHeader; - -/* No native methods here, but the constants are needed in the supporting JNI code */ -@GenerateNativeHeader final class LWTextFieldPeer extends LWTextComponentPeer<TextField, JPasswordField> implements TextFieldPeer, ActionListener { - private static final int DEFAULT_COLUMNS = 1; - LWTextFieldPeer(final TextField target, final PlatformComponent platformComponent) { super(target, platformComponent); @@ -83,17 +77,12 @@ @Override public Dimension getPreferredSize(final int columns) { - return getPreferredSize(1, columns); + return getMinimumSize(columns); } @Override public Dimension getMinimumSize(final int columns) { - return getPreferredSize(columns); - } - - @Override - public Dimension getMinimumSize() { - return getMinimumSize(DEFAULT_COLUMNS); + return getMinimumSize(1, columns); } @Override
--- a/src/macosx/classes/sun/lwawt/LWToolkit.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/LWToolkit.java Thu Oct 11 16:59:50 2012 -0700 @@ -310,7 +310,7 @@ @Override public CanvasPeer createCanvas(Canvas target) { PlatformComponent platformComponent = createPlatformComponent(); - LWCanvasPeer peer = new LWCanvasPeer(target, platformComponent); + LWCanvasPeer<?, ?> peer = new LWCanvasPeer<>(target, platformComponent); targetCreatedPeer(target, peer); peer.initialize(); return peer;
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Thu Oct 11 16:59:50 2012 -0700 @@ -160,6 +160,9 @@ if(isDeadChar){ testChar = (char) out[2]; + if(testChar == 0){ + return; + } } jkeyCode = out[0];
--- a/src/macosx/native/apple/security/KeystoreImpl.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/apple/security/KeystoreImpl.m Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -337,7 +337,6 @@ // Call back to the Java object to create Java objects corresponding to this security object. jlong nativeKeyRef = ptr_to_jlong(privateKeyRef); JNFCallVoidMethod(env, keyStore, jm_createKeyEntry, alias, creationDate, nativeKeyRef, certRefArray, javaCertArray); - break; } } while (searchResult == noErr);
--- a/src/macosx/native/sun/awt/AWTEvent.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/awt/AWTEvent.m Thu Oct 11 16:59:50 2012 -0700 @@ -383,6 +383,7 @@ { TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + if (uchr == nil) { return; } const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); // Carbon modifiers should be used instead of NSEvent modifiers UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF; @@ -563,18 +564,18 @@ const struct _nsKeyToJavaModifier* cur; for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) { - jint mask = isExtMods? cur->javaExtMask : cur->javaMask; + jint mask = isExtMods? cur->javaExtMask : cur->javaMask; if ((mask & javaModifiers) != 0) { nsFlags |= cur->nsMask; } } // special case - jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK : + jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK : java_awt_event_InputEvent_ALT_GRAPH_MASK; if ((mask & javaModifiers) != 0) { - nsFlags |= NSAlternateKeyMask; + nsFlags |= NSAlternateKeyMask; } return nsFlags;
--- a/src/macosx/native/sun/awt/AWTView.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/awt/AWTView.m Thu Oct 11 16:59:50 2012 -0700 @@ -279,7 +279,10 @@ return; } - if (![self hasMarkedText] && fKeyEventsNeeded) { + NSString *eventCharacters = [event characters]; + BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0); + + if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) { [self deliverJavaKeyEventHelper: event]; }
--- a/src/macosx/native/sun/awt/CTextPipe.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/awt/CTextPipe.m Thu Oct 11 16:59:50 2012 -0700 @@ -142,8 +142,11 @@ // get our baseline transform and font CGContextRef cgRef = qsdo->cgRef; CGAffineTransform ctmText = CGContextGetTextMatrix(cgRef); - //CGFontRef cgFont = CGContextGetFont(cgRef); + /* Save and restore of graphics context is done before the iteration. + This seems to work using our test case (see bug ID 7158350) so we are restoring it at + the end of the for loop. If we find out that save/restore outside the loop + doesn't work on all cases then we will move the Save/Restore inside the loop.*/ CGContextSaveGState(cgRef); CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx); @@ -210,13 +213,9 @@ pt.x += advances[i].width; pt.y += advances[i].height; - // reset the font on the context after striking a unicode with CoreText - if (uniChar != 0) - { - // CGContextSetFont(cgRef, cgFont); - CGContextSaveGState(cgRef); - } } + // reset the font on the context after striking a unicode with CoreText + CGContextRestoreGState(cgRef); } // Using the Quartz Surface Data context, draw a hot-substituted character run
--- a/src/macosx/native/sun/awt/InitIDs.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/awt/InitIDs.m Thu Oct 11 16:59:50 2012 -0700 @@ -47,7 +47,10 @@ { } - +JNIEXPORT void JNICALL Java_java_awt_Choice_initIDs +(JNIEnv *env, jclass cls) +{ +} JNIEXPORT void JNICALL Java_java_awt_Color_initIDs (JNIEnv *env, jclass cls)
--- a/src/macosx/native/sun/awt/LWCToolkit.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/awt/LWCToolkit.m Thu Oct 11 16:59:50 2012 -0700 @@ -33,6 +33,7 @@ #import "ThreadUtilities.h" #import "AWT_debug.h" #import "CSystemColors.h" +#import "NSApplicationAWT.h" #import "sun_lwawt_macosx_LWCToolkit.h" @@ -47,7 +48,7 @@ return eventCount; } -+ (void) eventCountPlusPlus{ ++ (void) eventCountPlusPlus{ eventCount++; } @@ -79,7 +80,6 @@ @end - /* * Class: sun_lwawt_macosx_LWCToolkit * Method: nativeSyncQueue @@ -90,12 +90,22 @@ { int currentEventNum = [AWTToolkit getEventCount]; - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}]; - + NSApplication* sharedApp = [NSApplication sharedApplication]; + if ([sharedApp isKindOfClass:[NSApplicationAWT class]]) { + NSApplicationAWT* theApp = (NSApplicationAWT*)sharedApp; + [theApp postDummyEvent]; + [theApp waitForDummyEvent]; + } else { + // could happen if we are embedded inside SWT application, + // in this case just spin a single empty block through + // the event loop to give it a chance to process pending events + [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}]; + } + if (([AWTToolkit getEventCount] - currentEventNum) != 0) { return JNI_TRUE; } - + return JNI_FALSE; }
--- a/src/macosx/native/sun/osxapp/NSApplicationAWT.h Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/osxapp/NSApplicationAWT.h Thu Oct 11 16:59:50 2012 -0700 @@ -29,11 +29,15 @@ @interface NSApplicationAWT : NSApplication { NSString *fApplicationName; NSWindow *eventTransparentWindow; + NSTimeInterval dummyEventTimestamp; + NSConditionLock* seenDummyEventLock; } - (void) finishLaunching; - (void) registerWithProcessManager; - (void) setDockIconWithEnv:(JNIEnv *)env; +- (void) postDummyEvent; +- (void) waitForDummyEvent; + (void) runAWTLoopWithApp:(NSApplication*)app;
--- a/src/macosx/native/sun/osxapp/NSApplicationAWT.m Thu Oct 11 09:50:14 2012 -0700 +++ b/src/macosx/native/sun/osxapp/NSApplicationAWT.m Thu Oct 11 16:59:50 2012 -0700 @@ -31,6 +31,7 @@ #import "PropertiesUtilities.h" #import "ThreadUtilities.h" #import "QueuingApplicationDelegate.h" +#import "AWTIconData.h" static BOOL sUsingDefaultNIB = YES; @@ -52,6 +53,9 @@ AWT_ASSERT_APPKIT_THREAD; fApplicationName = nil; + dummyEventTimestamp = 0.0; + seenDummyEventLock = nil; + // NSApplication will call _RegisterApplication with the application's bundle, but there may not be one. // So, we need to call it ourselves to ensure the app is set up properly. @@ -255,25 +259,26 @@ theIconPath = [PropertiesUtilities javaSystemPropertyForKey:@"apple.awt.application.icon" withEnv:env]; } - // If the icon file wasn't specified as an argument and we need to get an icon - // we'll use the generic java app icon. - NSString *defaultIconPath = [NSString stringWithFormat:@"%@%@", SHARED_FRAMEWORK_BUNDLE, @"/Resources/GenericApp.icns"]; - if (theIconPath == nil) { + // Use the path specified to get the icon image + NSImage* iconImage = nil; + if (theIconPath != nil) { + iconImage = [[NSImage alloc] initWithContentsOfFile:theIconPath]; + } + + // If no icon file was specified or we failed to get the icon image + // and there is no bundle's icon, then use the default icon + if (iconImage == nil) { NSString* bundleIcon = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIconFile"]; if (bundleIcon == nil) { - theIconPath = defaultIconPath; + NSData* iconData; + iconData = [[NSData alloc] initWithBytesNoCopy: sAWTIconData length: sizeof(sAWTIconData) freeWhenDone: NO]; + iconImage = [[NSImage alloc] initWithData: iconData]; + [iconData release]; } } - // Set up the dock icon if we have an icon name. - if (theIconPath != nil) { - NSImage *iconImage = [[NSImage alloc] initWithContentsOfFile:theIconPath]; - - // If we failed for some reason fall back to the default icon. - if (iconImage == nil) { - iconImage = [[NSImage alloc] initWithContentsOfFile:defaultIconPath]; - } - + // Set up the dock icon if we have an icon image. + if (iconImage != nil) { [NSApp setApplicationIconImage:iconImage]; [iconImage release]; } @@ -328,6 +333,45 @@ return event; } +// NSTimeInterval has microseconds precision +#define TS_EQUAL(ts1, ts2) (fabs((ts1) - (ts2)) < 1e-6) + +- (void)sendEvent:(NSEvent *)event +{ + if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp)) { + [seenDummyEventLock lockWhenCondition:NO]; + [seenDummyEventLock unlockWithCondition:YES]; + } else { + [super sendEvent:event]; + } +} + +- (void)postDummyEvent { + seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO]; + dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSMakePoint(0,0) + modifierFlags: 0 + timestamp: dummyEventTimestamp + windowNumber: 0 + context: nil + subtype: 0 + data1: 0 + data2: 0]; + [NSApp postEvent: event atStart: NO]; + [pool drain]; +} + +- (void)waitForDummyEvent { + [seenDummyEventLock lockWhenCondition:YES]; + [seenDummyEventLock unlock]; + [seenDummyEventLock release]; + + seenDummyEventLock = nil; +} + @end
--- a/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Thu Oct 11 16:59:50 2012 -0700 @@ -1064,12 +1064,17 @@ if (storeKey) { if (encKeys == null) { - if (!privCredSet.contains(ktab)) { - privCredSet.add(ktab); - // Compatibility; also add keys to privCredSet - for (KerberosKey key: ktab.getKeys(kerbClientPrinc)) { - privCredSet.add(new Krb5Util.KeysFromKeyTab(key)); + if (ktab != null) { + if (!privCredSet.contains(ktab)) { + privCredSet.add(ktab); + // Compatibility; also add keys to privCredSet + for (KerberosKey key: ktab.getKeys(kerbClientPrinc)) { + privCredSet.add(new Krb5Util.KeysFromKeyTab(key)); + } } + } else { + succeeded = false; + throw new LoginException("No key to store"); } } else { for (int i = 0; i < kerbKeys.length; i ++) {
--- a/src/share/classes/java/awt/Choice.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/awt/Choice.java Thu Oct 11 16:59:50 2012 -0700 @@ -104,7 +104,16 @@ /* * JDK 1.1 serialVersionUID */ - private static final long serialVersionUID = -4075310674757313071L; + private static final long serialVersionUID = -4075310674757313071L; + + static { + /* ensure that the necessary native libraries are loaded */ + Toolkit.loadLibraries(); + /* initialize JNI field and method ids */ + if (!GraphicsEnvironment.isHeadless()) { + initIDs(); + } + } /** * Creates a new choice menu. The menu initially has no items in it. @@ -711,6 +720,10 @@ } } + /** + * Initialize JNI field and method IDs + */ + private static native void initIDs(); ///////////////// // Accessibility support
--- a/src/share/classes/java/io/FilePermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/io/FilePermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -76,7 +76,7 @@ * <P> * Be careful when granting FilePermissions. Think about the implications * of granting read and especially write access to various files and - * directories. The "<<ALL FILES>>" permission with write action is + * directories. The "<<ALL FILES>>" permission with write action is * especially dangerous. This grants permission to write to the entire * file system. One thing this effectively allows is replacement of the * system binary, including the JVM runtime environment. @@ -180,9 +180,7 @@ * @param mask the actions mask to use. * */ - private void init(int mask) - { - + private void init(int mask) { if ((mask & ALL) != mask) throw new IllegalArgumentException("invalid actions mask"); @@ -274,9 +272,7 @@ * If actions is <code>null</code>, empty or contains an action * other than the specified possible actions. */ - - public FilePermission(String path, String actions) - { + public FilePermission(String path, String actions) { super(path); init(getMask(actions)); } @@ -293,8 +289,7 @@ */ // package private for use by the FilePermissionCollection add method - FilePermission(String path, int mask) - { + FilePermission(String path, int mask) { super(path); init(mask); } @@ -337,7 +332,6 @@ * this FilePermission's path also implies that FilePermission's path. * * @param that the FilePermission to check against. - * @param exact return immediately if the masks are not equal * @return the effective mask */ boolean impliesIgnoreMask(FilePermission that) { @@ -412,7 +406,6 @@ * * @return a hash code value for this object. */ - public int hashCode() { return this.cpath.hashCode(); } @@ -424,7 +417,6 @@ * @return the actions mask. */ private static int getMask(String actions) { - int mask = NONE; // Null action valid? @@ -552,7 +544,6 @@ * * @return the actions mask. */ - int getMask() { return mask; } @@ -564,8 +555,7 @@ * * @return the canonical string representation of the actions. */ - private static String getActions(int mask) - { + private static String getActions(int mask) { StringBuilder sb = new StringBuilder(); boolean comma = false; @@ -610,15 +600,13 @@ * * @return the canonical string representation of the actions. */ - public String getActions() - { + public String getActions() { if (actions == null) actions = getActions(this.mask); return actions; } - /** * Returns a new PermissionCollection object for storing FilePermission * objects. @@ -650,7 +638,6 @@ * @return a new PermissionCollection object suitable for storing * FilePermissions. */ - public PermissionCollection newPermissionCollection() { return new FilePermissionCollection(); } @@ -712,22 +699,20 @@ */ final class FilePermissionCollection extends PermissionCollection -implements Serializable { - + implements Serializable +{ // Not serialized; see serialization section at end of class private transient List<Permission> perms; /** - * Create an empty FilePermissions object. - * + * Create an empty FilePermissionCollection object. */ - public FilePermissionCollection() { perms = new ArrayList<>(); } /** - * Adds a permission to the FilePermissions. The key for the hash is + * Adds a permission to the FilePermissionCollection. The key for the hash is * permission.path. * * @param permission the Permission object to add. @@ -738,9 +723,7 @@ * @exception SecurityException - if this FilePermissionCollection object * has been marked readonly */ - - public void add(Permission permission) - { + public void add(Permission permission) { if (! (permission instanceof FilePermission)) throw new IllegalArgumentException("invalid permission: "+ permission); @@ -757,16 +740,14 @@ * Check and see if this set of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if "permission" is a proper subset of a permission in * the set, false if not. */ - - public boolean implies(Permission permission) - { + public boolean implies(Permission permission) { if (! (permission instanceof FilePermission)) - return false; + return false; FilePermission fp = (FilePermission) permission; @@ -795,7 +776,6 @@ * * @return an enumeration of all the FilePermission objects. */ - public Enumeration<Permission> elements() { // Convert Iterator into Enumeration synchronized (this) { @@ -841,8 +821,9 @@ /* * Reads in a Vector of FilePermissions and saves them in the perms field. */ - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { // Don't call defaultReadObject() // Read in serialized fields
--- a/src/share/classes/java/io/ObjectOutputStream.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/io/ObjectOutputStream.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -484,7 +484,7 @@ * stream. The state is reset to be the same as a new ObjectOutputStream. * The current point in the stream is marked as reset so the corresponding * ObjectInputStream will be reset at the same point. Objects previously - * written to the stream will not be refered to as already being in the + * written to the stream will not be referred to as already being in the * stream. They will be written to the stream again. * * @throws IOException if reset() is invoked while serializing an object.
--- a/src/share/classes/java/io/PrintWriter.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/io/PrintWriter.java Thu Oct 11 16:59:50 2012 -0700 @@ -784,7 +784,7 @@ * <tt>null</tt> argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * - * @throws IllegalFormatException + * @throws java.util.IllegalFormatException * If a format string contains an illegal syntax, a format * specifier that is incompatible with the given arguments, * insufficient arguments given the format string, or other @@ -835,7 +835,7 @@ * <tt>null</tt> argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * - * @throws IllegalFormatException + * @throws java.util.IllegalFormatException * If a format string contains an illegal syntax, a format * specifier that is incompatible with the given arguments, * insufficient arguments given the format string, or other @@ -879,7 +879,7 @@ * <tt>null</tt> argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * - * @throws IllegalFormatException + * @throws java.util.IllegalFormatException * If a format string contains an illegal syntax, a format * specifier that is incompatible with the given arguments, * insufficient arguments given the format string, or other @@ -939,7 +939,7 @@ * <tt>null</tt> argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * - * @throws IllegalFormatException + * @throws java.util.IllegalFormatException * If a format string contains an illegal syntax, a format * specifier that is incompatible with the given arguments, * insufficient arguments given the format string, or other
--- a/src/share/classes/java/io/Reader.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/io/Reader.java Thu Oct 11 16:59:50 2012 -0700 @@ -91,7 +91,7 @@ * -1 if this source of characters is at its end * @throws IOException if an I/O error occurs * @throws NullPointerException if target is null - * @throws ReadOnlyBufferException if target is a read only buffer + * @throws java.nio.ReadOnlyBufferException if target is a read only buffer * @since 1.5 */ public int read(java.nio.CharBuffer target) throws IOException {
--- a/src/share/classes/java/lang/Class.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/Class.java Thu Oct 11 16:59:50 2012 -0700 @@ -2970,7 +2970,7 @@ /** * Returns a map from simple name to enum constant. This package-private * method is used internally by Enum to implement - * public static <T extends Enum<T>> T valueOf(Class<T>, String) + * {@code public static <T extends Enum<T>> T valueOf(Class<T>, String)} * efficiently. Note that the map is returned by this method is * created lazily on first use. Typically it won't ever get created. */
--- a/src/share/classes/java/lang/InheritableThreadLocal.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/InheritableThreadLocal.java Thu Oct 11 16:59:50 2012 -0700 @@ -76,7 +76,6 @@ * * @param t the current thread * @param firstValue value for the initial entry of the table. - * @param map the map to store. */ void createMap(Thread t, T firstValue) { t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
--- a/src/share/classes/java/lang/Integer.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/Integer.java Thu Oct 11 16:59:50 2012 -0700 @@ -752,7 +752,7 @@ * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache - * may be controlled by the -XX:AutoBoxCacheMax=<size> option. + * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class.
--- a/src/share/classes/java/lang/Package.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/Package.java Thu Oct 11 16:59:50 2012 -0700 @@ -316,7 +316,7 @@ * attributes are defined in the manifests that accompany * the classes. * - * @param class the class to get the package of. + * @param c the class to get the package of. * @return the package of the class. It may be null if no package * information is available from the archive or codebase. */ static Package getPackage(Class<?> c) { @@ -411,14 +411,13 @@ /** * Construct a package instance with the specified version * information. - * @param pkgName the name of the package + * @param name the name of the package * @param spectitle the title of the specification * @param specversion the version of the specification * @param specvendor the organization that maintains the specification * @param impltitle the title of the implementation * @param implversion the version of the implementation * @param implvendor the organization that maintains the implementation - * @return a new package for containing the specified information. */ Package(String name, String spectitle, String specversion, String specvendor,
--- a/src/share/classes/java/lang/StrictMath.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/StrictMath.java Thu Oct 11 16:59:50 2012 -0700 @@ -365,7 +365,7 @@ * @param a the value to be floored or ceiled * @param negativeBoundary result for values in (-1, 0) * @param positiveBoundary result for values in (0, 1) - * @param increment value to add when the argument is non-integral + * @param sign the sign of the result */ private static double floorOrCeil(double a, double negativeBoundary, @@ -811,7 +811,7 @@ * @param value the long value * @return the argument as an int * @throws ArithmeticException if the {@code argument} overflows an int - * @see Math#toIntExact(int) + * @see Math#toIntExact(long) * @since 1.8 */ public static int toIntExact(long value) {
--- a/src/share/classes/java/lang/String.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/String.java Thu Oct 11 16:59:50 2012 -0700 @@ -2782,7 +2782,7 @@ * <tt>null</tt> argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * - * @throws IllegalFormatException + * @throws java.util.IllegalFormatException * If a format string contains an illegal syntax, a format * specifier that is incompatible with the given arguments, * insufficient arguments given the format string, or other @@ -2826,7 +2826,7 @@ * <tt>null</tt> argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * - * @throws IllegalFormatException + * @throws java.util.IllegalFormatException * If a format string contains an illegal syntax, a format * specifier that is incompatible with the given arguments, * insufficient arguments given the format string, or other
--- a/src/share/classes/java/lang/System.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/System.java Thu Oct 11 16:59:50 2012 -0700 @@ -545,7 +545,7 @@ * <tr><td><code>java.version</code></td> * <td>Java Runtime Environment version</td></tr> * <tr><td><code>java.vendor</code></td> - * <td>Java Runtime Environment vendor</td></tr + * <td>Java Runtime Environment vendor</td></tr> * <tr><td><code>java.vendor.url</code></td> * <td>Java vendor URL</td></tr> * <tr><td><code>java.home</code></td>
--- a/src/share/classes/java/lang/ThreadGroup.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/ThreadGroup.java Thu Oct 11 16:59:50 2012 -0700 @@ -918,9 +918,6 @@ * * @param t * the Thread whose start method was invoked - * - * @param failed - * true if the thread could not be started successfully */ void threadStartFailed(Thread t) { synchronized(this) {
--- a/src/share/classes/java/lang/ThreadLocal.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/ThreadLocal.java Thu Oct 11 16:59:50 2012 -0700 @@ -47,8 +47,8 @@ * private static final AtomicInteger nextId = new AtomicInteger(0); * * // Thread local variable containing each thread's ID - * private static final ThreadLocal<Integer> threadId = - * new ThreadLocal<Integer>() { + * private static final ThreadLocal<Integer> threadId = + * new ThreadLocal<Integer>() { * @Override protected Integer initialValue() { * return nextId.getAndIncrement(); * } @@ -222,7 +222,6 @@ * * @param t the current thread * @param firstValue value for the initial entry of the map - * @param map the map to store. */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue);
--- a/src/share/classes/java/lang/management/ThreadInfo.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/lang/management/ThreadInfo.java Thu Oct 11 16:59:50 2012 -0700 @@ -147,8 +147,9 @@ * @param waitedCount Number of times waited on a lock * @param waitedTime Approx time waited on a lock * @param stackTrace Thread stack trace - * @param lockedMonitors List of locked monitors - * @param lockedSynchronizers List of locked synchronizers + * @param monitors List of locked monitors + * @param stackDepths List of stack depths + * @param synchronizers List of locked synchronizers */ private ThreadInfo(Thread t, int state, Object lockObj, Thread lockOwner, long blockedCount, long blockedTime,
--- a/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -48,11 +48,6 @@ protected InetAddress connectedAddress = null; private int connectedPort = -1; - /* cached socket options */ - private int multicastInterface = 0; - private boolean loopbackMode = true; - private int ttl = -1; - private static final String os = AccessController.doPrivileged( new sun.security.action.GetPropertyAction("os.name") ); @@ -104,7 +99,7 @@ /** * Sends a datagram packet. The packet contains the data and the * destination address to send the packet to. - * @param packet to be sent. + * @param p the packet to be sent. */ protected abstract void send(DatagramPacket p) throws IOException; @@ -135,13 +130,13 @@ /** * Peek at the packet to see who it is from. - * @param return the address which the packet came from. + * @param i the address to populate with the sender address */ protected abstract int peek(InetAddress i) throws IOException; protected abstract int peekData(DatagramPacket p) throws IOException; /** * Receive the datagram packet. - * @param Packet Received. + * @param p the packet to receive into */ protected synchronized void receive(DatagramPacket p) throws IOException { @@ -153,7 +148,7 @@ /** * Set the TTL (time-to-live) option. - * @param TTL to be set. + * @param ttl TTL to be set. */ protected abstract void setTimeToLive(int ttl) throws IOException; @@ -164,7 +159,7 @@ /** * Set the TTL (time-to-live) option. - * @param TTL to be set. + * @param ttl TTL to be set. */ @Deprecated protected abstract void setTTL(byte ttl) throws IOException; @@ -177,7 +172,7 @@ /** * Join the multicast group. - * @param multicast address to join. + * @param inetaddr multicast address to join. */ protected void join(InetAddress inetaddr) throws IOException { join(inetaddr, null); @@ -185,14 +180,14 @@ /** * Leave the multicast group. - * @param multicast address to leave. + * @param inetaddr multicast address to leave. */ protected void leave(InetAddress inetaddr) throws IOException { leave(inetaddr, null); } /** * Join the multicast group. - * @param multicast address to join. + * @param mcastaddr multicast address to join. * @param netIf specifies the local interface to receive multicast * datagram packets * @throws IllegalArgumentException if mcastaddr is null or is a @@ -212,7 +207,7 @@ /** * Leave the multicast group. - * @param multicast address to leave. + * @param mcastaddr multicast address to leave. * @param netIf specified the local interface to leave the group at * @throws IllegalArgumentException if mcastaddr is null or is a * SocketAddress subclass not supported by this socket
--- a/src/share/classes/java/net/AbstractPlainSocketImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/AbstractPlainSocketImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -368,7 +368,7 @@ /** * Binds the socket to the specified address of the specified local port. * @param address the address - * @param port the port + * @param lport the port */ protected synchronized void bind(InetAddress address, int lport) throws IOException
--- a/src/share/classes/java/net/DatagramSocket.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/DatagramSocket.java Thu Oct 11 16:59:50 2012 -0700 @@ -105,7 +105,7 @@ * Connects this socket to a remote socket address (IP address + port number). * Binds socket if not already bound. * <p> - * @param addr The remote address. + * @param address The remote address. * @param port The remote port * @throws SocketException if binding the socket fails. */
--- a/src/share/classes/java/net/Inet4Address.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/Inet4Address.java Thu Oct 11 16:59:50 2012 -0700 @@ -177,7 +177,6 @@ * a loopback address; or false otherwise. * @since 1.4 */ - private static final int loopback = 2130706433; /* 127.0.0.1 */ public boolean isLoopbackAddress() { /* 127.x.x.x */ byte[] byteAddr = getAddress();
--- a/src/share/classes/java/net/SocketInputStream.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/SocketInputStream.java Thu Oct 11 16:59:50 2012 -0700 @@ -112,7 +112,7 @@ * <i>length</i> bytes of data. * @param b the buffer into which the data is read * @param off the start offset of the data - * @param len the maximum number of bytes read + * @param length the maximum number of bytes read * @return the actual number of bytes read, -1 is * returned when the end of the stream is reached. * @exception IOException If an I/O error has occurred. @@ -209,7 +209,7 @@ /** * Skips n bytes of input. - * @param n the number of bytes to skip + * @param numbytes the number of bytes to skip * @return the actual number of bytes skipped. * @exception IOException If an I/O error has occurred. */
--- a/src/share/classes/java/net/SocketPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/SocketPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -138,7 +138,7 @@ */ public final class SocketPermission extends Permission -implements java.io.Serializable + implements java.io.Serializable { private static final long serialVersionUID = -7204263841984476862L; @@ -232,8 +232,7 @@ trustNameService = tmp.booleanValue(); } - private static synchronized Debug getDebug() - { + private static synchronized Debug getDebug() { if (!debugInit) { debug = Debug.getInstance("access"); debugInit = true; @@ -288,8 +287,7 @@ defaultDeny = true; } - private static String getHost(String host) - { + private static String getHost(String host) { if (host.equals("")) { return "localhost"; } else { @@ -679,8 +677,8 @@ } private boolean authorizedIPv4(String cname, byte[] addr) { - String authHost = ""; - InetAddress auth; + String authHost = ""; + InetAddress auth; try { authHost = "auth." + @@ -708,8 +706,8 @@ } private boolean authorizedIPv6(String cname, byte[] addr) { - String authHost = ""; - InetAddress auth; + String authHost = ""; + InetAddress auth; try { StringBuffer sb = new StringBuffer(39); @@ -810,7 +808,6 @@ * @return true if the specified permission is implied by this object, * false if not. */ - public boolean implies(Permission p) { int i,j; @@ -844,12 +841,11 @@ * to find a match based on the IP addresses in both objects. * <li> Attempt to match on the canonical hostnames of both objects. * </ul> - * @param p the incoming permission request + * @param that the incoming permission request * * @return true if "permission" is a proper subset of the current object, * false if not. */ - boolean impliesIgnoreMask(SocketPermission that) { int i,j; @@ -1229,7 +1225,7 @@ */ final class SocketPermissionCollection extends PermissionCollection -implements Serializable + implements Serializable { // Not serialized; see serialization section at end of class private transient List<SocketPermission> perms; @@ -1255,9 +1251,7 @@ * @exception SecurityException - if this SocketPermissionCollection object * has been marked readonly */ - - public void add(Permission permission) - { + public void add(Permission permission) { if (! (permission instanceof SocketPermission)) throw new IllegalArgumentException("invalid permission: "+ permission); @@ -1276,7 +1270,7 @@ * Check and see if this collection of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if "permission" is a proper subset of a permission in * the collection, false if not. @@ -1369,8 +1363,9 @@ /* * Reads in a Vector of SocketPermissions and saves them in the perms field. */ - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { // Don't call in.defaultReadObject() // Read in serialized fields
--- a/src/share/classes/java/net/SocksSocketImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/SocksSocketImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -644,7 +644,7 @@ * means "accept incoming connection from", so the SocketAddress is the * the one of the host we do accept connection from. * - * @param addr the Socket address of the remote host. + * @param saddr the Socket address of the remote host. * @exception IOException if an I/O error occurs when binding this socket. */ protected synchronized void socksBind(InetSocketAddress saddr) throws IOException {
--- a/src/share/classes/java/net/URLConnection.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/net/URLConnection.java Thu Oct 11 16:59:50 2012 -0700 @@ -1241,10 +1241,9 @@ /** * Gets the Content Handler appropriate for this connection. - * @param connection the connection to use. */ synchronized ContentHandler getContentHandler() - throws UnknownServiceException + throws UnknownServiceException { String contentType = stripOffParameters(getContentType()); ContentHandler handler = null;
--- a/src/share/classes/java/nio/X-Buffer.java.template Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/X-Buffer.java.template Thu Oct 11 16:59:50 2012 -0700 @@ -741,6 +741,8 @@ public $Type$Buffer put($Type$Buffer src) { if (src == this) throw new IllegalArgumentException(); + if (isReadOnly()) + throw new ReadOnlyBufferException(); int n = src.remaining(); if (n > remaining()) throw new BufferOverflowException(); @@ -888,6 +890,8 @@ */ public $Type$Buffer put(String src, int start, int end) { checkBounds(start, end - start, src.length()); + if (isReadOnly()) + throw new ReadOnlyBufferException(); if (end - start > remaining()) throw new BufferOverflowException(); for (int i = start; i < end; i++)
--- a/src/share/classes/java/nio/channels/Channels.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/channels/Channels.java Thu Oct 11 16:59:50 2012 -0700 @@ -84,7 +84,7 @@ /** * Write all remaining bytes in buffer to the given channel. * - * @throws IllegalBlockingException + * @throws IllegalBlockingModeException * If the channel is selectable and configured non-blocking. */ private static void writeFully(WritableByteChannel ch, ByteBuffer bb)
--- a/src/share/classes/java/nio/file/FileSystem.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/file/FileSystem.java Thu Oct 11 16:59:50 2012 -0700 @@ -347,7 +347,7 @@ * <td><tt>C:\\*</tt> * <td>Matches <tt>C:\foo</tt> and <tt>C:\bar</tt> on the Windows * platform (note that the backslash is escaped; as a string literal in the - * Java Language the pattern would be <tt>"C:\\\\*"</tt>) </td> + * Java Language the pattern would be <tt>"C:\\\\*"</tt>) </td> * </tr> * * </table>
--- a/src/share/classes/java/nio/file/Files.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/file/Files.java Thu Oct 11 16:59:50 2012 -0700 @@ -510,7 +510,7 @@ * <pre> * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { * public boolean accept(Path file) throws IOException { - * return (Files.size(file) > 8192L); + * return (Files.size(file) > 8192L); * } * }; * Path dir = ... @@ -1592,7 +1592,7 @@ * Path path = ... * AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); * if (view != null) { - * List<AclEntry> acl = view.getAcl(); + * List<AclEntry> acl = view.getAcl(); * : * } * </pre>
--- a/src/share/classes/java/nio/file/Path.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/file/Path.java Thu Oct 11 16:59:50 2012 -0700 @@ -522,7 +522,7 @@ * * @return a {@code Path} object representing the absolute path * - * @throws IOError + * @throws java.io.IOError * if an I/O error occurs * @throws SecurityException * In the case of the default provider, a security manager
--- a/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/file/attribute/AclFileAttributeView.java Thu Oct 11 16:59:50 2012 -0700 @@ -85,7 +85,7 @@ * .build(); * * // read ACL, insert ACE, re-write ACL - * List<AclEntry> acl = view.getAcl(); + * List<AclEntry> acl = view.getAcl(); * acl.add(0, entry); // insert before any DENY entries * view.setAcl(acl); * </pre>
--- a/src/share/classes/java/nio/file/attribute/FileTime.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/nio/file/attribute/FileTime.java Thu Oct 11 16:59:50 2012 -0700 @@ -310,7 +310,7 @@ private final long days; /** - * The excess (in nanoseconds); can be negative if days <= 0. + * The excess (in nanoseconds); can be negative if days <= 0. */ private final long excessNanos;
--- a/src/share/classes/java/security/AllPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/security/AllPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -62,9 +62,7 @@ /** * Creates a new AllPermission object. */ - - public AllPermission() - { + public AllPermission() { super("<all permissions>"); } @@ -77,8 +75,7 @@ * @param name ignored * @param actions ignored. */ - public AllPermission(String name, String actions) - { + public AllPermission(String name, String actions) { this(); } @@ -120,8 +117,7 @@ * * @return the actions. */ - public String getActions() - { + public String getActions() { return "<all actions>"; } @@ -133,7 +129,6 @@ * @return a new PermissionCollection object suitable for * storing AllPermissions. */ - public PermissionCollection newPermissionCollection() { return new AllPermissionCollection(); } @@ -157,8 +152,8 @@ */ final class AllPermissionCollection -extends PermissionCollection -implements java.io.Serializable + extends PermissionCollection + implements java.io.Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability @@ -188,8 +183,7 @@ * has been marked readonly */ - public void add(Permission permission) - { + public void add(Permission permission) { if (! (permission instanceof AllPermission)) throw new IllegalArgumentException("invalid permission: "+ permission); @@ -203,13 +197,12 @@ * Check and see if this set of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return always returns true. */ - public boolean implies(Permission permission) - { + public boolean implies(Permission permission) { return all_allowed; // No sync; staleness OK } @@ -219,8 +212,7 @@ * * @return an enumeration of all the AllPermission objects. */ - public Enumeration<Permission> elements() - { + public Enumeration<Permission> elements() { return new Enumeration<Permission>() { private boolean hasMore = all_allowed;
--- a/src/share/classes/java/security/BasicPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/security/BasicPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -68,7 +68,7 @@ */ public abstract class BasicPermission extends Permission -implements java.io.Serializable + implements java.io.Serializable { private static final long serialVersionUID = 6279438298436773498L; @@ -84,10 +84,8 @@ /** * initialize a BasicPermission object. Common to all constructors. - * */ - private void init(String name) - { + private void init(String name) { if (name == null) throw new NullPointerException("name can't be null"); @@ -129,9 +127,7 @@ * @throws NullPointerException if <code>name</code> is <code>null</code>. * @throws IllegalArgumentException if <code>name</code> is empty. */ - - public BasicPermission(String name) - { + public BasicPermission(String name) { super(name); init(name); } @@ -148,8 +144,7 @@ * @throws NullPointerException if <code>name</code> is <code>null</code>. * @throws IllegalArgumentException if <code>name</code> is empty. */ - public BasicPermission(String name, String actions) - { + public BasicPermission(String name, String actions) { super(name); init(name); } @@ -238,8 +233,7 @@ * * @return the empty string "". */ - public String getActions() - { + public String getActions() { return ""; } @@ -296,7 +290,6 @@ * * @see java.security.Permission * @see java.security.Permissions - * @see java.security.PermissionsImpl * * * @author Roland Schemers @@ -305,8 +298,8 @@ */ final class BasicPermissionCollection -extends PermissionCollection -implements java.io.Serializable + extends PermissionCollection + implements java.io.Serializable { private static final long serialVersionUID = 739301742472979399L; @@ -360,9 +353,7 @@ * @exception SecurityException - if this BasicPermissionCollection object * has been marked readonly */ - - public void add(Permission permission) - { + public void add(Permission permission) { if (! (permission instanceof BasicPermission)) throw new IllegalArgumentException("invalid permission: "+ permission); @@ -398,16 +389,14 @@ * Check and see if this set of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if "permission" is a proper subset of a permission in * the set, false if not. */ - - public boolean implies(Permission permission) - { + public boolean implies(Permission permission) { if (! (permission instanceof BasicPermission)) - return false; + return false; BasicPermission bp = (BasicPermission) permission; @@ -468,7 +457,6 @@ * * @return an enumeration of all the BasicPermission objects. */ - public Enumeration<Permission> elements() { // Convert Iterator of Map values into an Enumeration synchronized (this) {
--- a/src/share/classes/java/security/CodeSource.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/security/CodeSource.java Thu Oct 11 16:59:50 2012 -0700 @@ -207,7 +207,7 @@ * Returns the code signers associated with this CodeSource. * <p> * If this CodeSource object was created using the - * {@link #CodeSource(URL url, Certificate[] certs)} + * {@link #CodeSource(URL url, java.security.cert.Certificate[] certs)} * constructor then its certificate chains are extracted and used to * create an array of CodeSigner objects. Note that only X.509 certificates * are examined - all other certificate types are ignored.
--- a/src/share/classes/java/security/KeyStore.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/security/KeyStore.java Thu Oct 11 16:59:50 2012 -0700 @@ -32,6 +32,7 @@ import java.util.*; import javax.crypto.SecretKey; +import javax.security.auth.DestroyFailedException; import javax.security.auth.callback.*; /** @@ -278,8 +279,7 @@ * @exception DestroyFailedException if this method was unable * to clear the password */ - public synchronized void destroy() - throws javax.security.auth.DestroyFailedException { + public synchronized void destroy() throws DestroyFailedException { destroyed = true; if (password != null) { Arrays.fill(password, ' ');
--- a/src/share/classes/java/security/cert/PKIXRevocationChecker.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/security/cert/PKIXRevocationChecker.java Thu Oct 11 16:59:50 2012 -0700 @@ -50,7 +50,7 @@ * status of certificates with OCSP and CRLs. By default, OCSP is the * preferred mechanism for checking revocation status, with CRLs as the * fallback mechanism. However, this preference can be switched to CRLs with - * the {@link Option.PREFER_CRLS} option. + * the {@link Option#PREFER_CRLS PREFER_CRLS} option. * * <p>A {@code PKIXRevocationChecker} is obtained by calling the * {@link CertPathValidator#getRevocationChecker getRevocationChecker} method
--- a/src/share/classes/java/sql/CallableStatement.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/sql/CallableStatement.java Thu Oct 11 16:59:50 2012 -0700 @@ -1562,7 +1562,7 @@ * @param parameterName the name of the parameter * @return the parameter value in full precision. If the value is * SQL <code>NULL</code>, the result is <code>null</code>. - * @exception SQLExceptionif parameterName does not correspond to a named + * @exception SQLException if parameterName does not correspond to a named * parameter; if a database access error occurs or * this method is called on a closed <code>CallableStatement</code> * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
--- a/src/share/classes/java/text/CollationElementIterator.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/CollationElementIterator.java Thu Oct 11 16:59:50 2012 -0700 @@ -119,7 +119,7 @@ * on the predefined collation rules. If the source string is empty, * NULLORDER will be returned on the calls to next(). * @param sourceText the source string. - * @param order the collation object. + * @param owner the collation object. */ CollationElementIterator(String sourceText, RuleBasedCollator owner) { this.owner = owner; @@ -137,7 +137,7 @@ * on the predefined collation rules. If the source string is empty, * NULLORDER will be returned on the calls to next(). * @param sourceText the source string. - * @param order the collation object. + * @param owner the collation object. */ CollationElementIterator(CharacterIterator sourceText, RuleBasedCollator owner) { this.owner = owner;
--- a/src/share/classes/java/text/DecimalFormat.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/DecimalFormat.java Thu Oct 11 16:59:50 2012 -0700 @@ -529,9 +529,25 @@ @Override public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) { - fieldPosition.setBeginIndex(0); - fieldPosition.setEndIndex(0); - + // If fieldPosition is a DontCareFieldPosition instance we can + // try to go to fast-path code. + boolean tryFastPath = false; + if (fieldPosition == DontCareFieldPosition.INSTANCE) + tryFastPath = true; + else { + fieldPosition.setBeginIndex(0); + fieldPosition.setEndIndex(0); + } + + if (tryFastPath) { + String tempResult = fastFormat(number); + if (tempResult != null) { + result.append(tempResult); + return result; + } + } + + // if fast-path could not work, we fallback to standard code. return format(number, result, fieldPosition.getFieldDelegate()); } @@ -869,6 +885,720 @@ return delegate.getIterator(sb.toString()); } + // ==== Begin fast-path formating logic for double ========================= + + /* Fast-path formatting will be used for format(double ...) methods iff a + * number of conditions are met (see checkAndSetFastPathStatus()): + * - Only if instance properties meet the right predefined conditions. + * - The abs value of the double to format is <= Integer.MAX_VALUE. + * + * The basic approach is to split the binary to decimal conversion of a + * double value into two phases: + * * The conversion of the integer portion of the double. + * * The conversion of the fractional portion of the double + * (limited to two or three digits). + * + * The isolation and conversion of the integer portion of the double is + * straightforward. The conversion of the fraction is more subtle and relies + * on some rounding properties of double to the decimal precisions in + * question. Using the terminology of BigDecimal, this fast-path algorithm + * is applied when a double value has a magnitude less than Integer.MAX_VALUE + * and rounding is to nearest even and the destination format has two or + * three digits of *scale* (digits after the decimal point). + * + * Under a rounding to nearest even policy, the returned result is a digit + * string of a number in the (in this case decimal) destination format + * closest to the exact numerical value of the (in this case binary) input + * value. If two destination format numbers are equally distant, the one + * with the last digit even is returned. To compute such a correctly rounded + * value, some information about digits beyond the smallest returned digit + * position needs to be consulted. + * + * In general, a guard digit, a round digit, and a sticky *bit* are needed + * beyond the returned digit position. If the discarded portion of the input + * is sufficiently large, the returned digit string is incremented. In round + * to nearest even, this threshold to increment occurs near the half-way + * point between digits. The sticky bit records if there are any remaining + * trailing digits of the exact input value in the new format; the sticky bit + * is consulted only in close to half-way rounding cases. + * + * Given the computation of the digit and bit values, rounding is then + * reduced to a table lookup problem. For decimal, the even/odd cases look + * like this: + * + * Last Round Sticky + * 6 5 0 => 6 // exactly halfway, return even digit. + * 6 5 1 => 7 // a little bit more than halfway, round up. + * 7 5 0 => 8 // exactly halfway, round up to even. + * 7 5 1 => 8 // a little bit more than halfway, round up. + * With analogous entries for other even and odd last-returned digits. + * + * However, decimal negative powers of 5 smaller than 0.5 are *not* exactly + * representable as binary fraction. In particular, 0.005 (the round limit + * for a two-digit scale) and 0.0005 (the round limit for a three-digit + * scale) are not representable. Therefore, for input values near these cases + * the sticky bit is known to be set which reduces the rounding logic to: + * + * Last Round Sticky + * 6 5 1 => 7 // a little bit more than halfway, round up. + * 7 5 1 => 8 // a little bit more than halfway, round up. + * + * In other words, if the round digit is 5, the sticky bit is known to be + * set. If the round digit is something other than 5, the sticky bit is not + * relevant. Therefore, some of the logic about whether or not to increment + * the destination *decimal* value can occur based on tests of *binary* + * computations of the binary input number. + */ + + /** + * Check validity of using fast-path for this instance. If fast-path is valid + * for this instance, sets fast-path state as true and initializes fast-path + * utility fields as needed. + * + * This method is supposed to be called rarely, otherwise that will break the + * fast-path performance. That means avoiding frequent changes of the + * properties of the instance, since for most properties, each time a change + * happens, a call to this method is needed at the next format call. + * + * FAST-PATH RULES: + * Similar to the default DecimalFormat instantiation case. + * More precisely: + * - HALF_EVEN rounding mode, + * - isGroupingUsed() is true, + * - groupingSize of 3, + * - multiplier is 1, + * - Decimal separator not mandatory, + * - No use of exponential notation, + * - minimumIntegerDigits is exactly 1 and maximumIntegerDigits at least 10 + * - For number of fractional digits, the exact values found in the default case: + * Currency : min = max = 2. + * Decimal : min = 0. max = 3. + * + */ + private void checkAndSetFastPathStatus() { + + boolean fastPathWasOn = isFastPath; + + if ((roundingMode == RoundingMode.HALF_EVEN) && + (isGroupingUsed()) && + (groupingSize == 3) && + (multiplier == 1) && + (!decimalSeparatorAlwaysShown) && + (!useExponentialNotation)) { + + // The fast-path algorithm is semi-hardcoded against + // minimumIntegerDigits and maximumIntegerDigits. + isFastPath = ((minimumIntegerDigits == 1) && + (maximumIntegerDigits >= 10)); + + // The fast-path algorithm is hardcoded against + // minimumFractionDigits and maximumFractionDigits. + if (isFastPath) { + if (isCurrencyFormat) { + if ((minimumFractionDigits != 2) || + (maximumFractionDigits != 2)) + isFastPath = false; + } else if ((minimumFractionDigits != 0) || + (maximumFractionDigits != 3)) + isFastPath = false; + } + } else + isFastPath = false; + + // Since some instance properties may have changed while still falling + // in the fast-path case, we need to reinitialize fastPathData anyway. + if (isFastPath) { + // We need to instantiate fastPathData if not already done. + if (fastPathData == null) + fastPathData = new FastPathData(); + + // Sets up the locale specific constants used when formatting. + // '0' is our default representation of zero. + fastPathData.zeroDelta = symbols.getZeroDigit() - '0'; + fastPathData.groupingChar = symbols.getGroupingSeparator(); + + // Sets up fractional constants related to currency/decimal pattern. + fastPathData.fractionalMaxIntBound = (isCurrencyFormat) ? 99 : 999; + fastPathData.fractionalScaleFactor = (isCurrencyFormat) ? 100.0d : 1000.0d; + + // Records the need for adding prefix or suffix + fastPathData.positiveAffixesRequired = + (positivePrefix.length() != 0) || (positiveSuffix.length() != 0); + fastPathData.negativeAffixesRequired = + (negativePrefix.length() != 0) || (negativeSuffix.length() != 0); + + // Creates a cached char container for result, with max possible size. + int maxNbIntegralDigits = 10; + int maxNbGroups = 3; + int containerSize = + Math.max(positivePrefix.length(), negativePrefix.length()) + + maxNbIntegralDigits + maxNbGroups + 1 + maximumFractionDigits + + Math.max(positiveSuffix.length(), negativeSuffix.length()); + + fastPathData.fastPathContainer = new char[containerSize]; + + // Sets up prefix and suffix char arrays constants. + fastPathData.charsPositiveSuffix = positiveSuffix.toCharArray(); + fastPathData.charsNegativeSuffix = negativeSuffix.toCharArray(); + fastPathData.charsPositivePrefix = positivePrefix.toCharArray(); + fastPathData.charsNegativePrefix = negativePrefix.toCharArray(); + + // Sets up fixed index positions for integral and fractional digits. + // Sets up decimal point in cached result container. + int longestPrefixLength = + Math.max(positivePrefix.length(), negativePrefix.length()); + int decimalPointIndex = + maxNbIntegralDigits + maxNbGroups + longestPrefixLength; + + fastPathData.integralLastIndex = decimalPointIndex - 1; + fastPathData.fractionalFirstIndex = decimalPointIndex + 1; + fastPathData.fastPathContainer[decimalPointIndex] = + isCurrencyFormat ? + symbols.getMonetaryDecimalSeparator() : + symbols.getDecimalSeparator(); + + } else if (fastPathWasOn) { + // Previous state was fast-path and is no more. + // Resets cached array constants. + fastPathData.fastPathContainer = null; + fastPathData.charsPositiveSuffix = null; + fastPathData.charsNegativeSuffix = null; + fastPathData.charsPositivePrefix = null; + fastPathData.charsNegativePrefix = null; + } + + fastPathCheckNeeded = false; + } + + /** + * Returns true if rounding-up must be done on {@code scaledFractionalPartAsInt}, + * false otherwise. + * + * This is a utility method that takes correct half-even rounding decision on + * passed fractional value at the scaled decimal point (2 digits for currency + * case and 3 for decimal case), when the approximated fractional part after + * scaled decimal point is exactly 0.5d. This is done by means of exact + * calculations on the {@code fractionalPart} floating-point value. + * + * This method is supposed to be called by private {@code fastDoubleFormat} + * method only. + * + * The algorithms used for the exact calculations are : + * + * The <b><i>FastTwoSum</i></b> algorithm, from T.J.Dekker, described in the + * papers "<i>A Floating-Point Technique for Extending the Available + * Precision</i>" by Dekker, and in "<i>Adaptive Precision Floating-Point + * Arithmetic and Fast Robust Geometric Predicates</i>" from J.Shewchuk. + * + * A modified version of <b><i>Sum2S</i></b> cascaded summation described in + * "<i>Accurate Sum and Dot Product</i>" from Takeshi Ogita and All. As + * Ogita says in this paper this is an equivalent of the Kahan-Babuska's + * summation algorithm because we order the terms by magnitude before summing + * them. For this reason we can use the <i>FastTwoSum</i> algorithm rather + * than the more expensive Knuth's <i>TwoSum</i>. + * + * We do this to avoid a more expensive exact "<i>TwoProduct</i>" algorithm, + * like those described in Shewchuk's paper above. See comments in the code + * below. + * + * @param fractionalPart The fractional value on which we take rounding + * decision. + * @param scaledFractionalPartAsInt The integral part of the scaled + * fractional value. + * + * @return the decision that must be taken regarding half-even rounding. + */ + private boolean exactRoundUp(double fractionalPart, + int scaledFractionalPartAsInt) { + + /* exactRoundUp() method is called by fastDoubleFormat() only. + * The precondition expected to be verified by the passed parameters is : + * scaledFractionalPartAsInt == + * (int) (fractionalPart * fastPathData.fractionalScaleFactor). + * This is ensured by fastDoubleFormat() code. + */ + + /* We first calculate roundoff error made by fastDoubleFormat() on + * the scaled fractional part. We do this with exact calculation on the + * passed fractionalPart. Rounding decision will then be taken from roundoff. + */ + + /* ---- TwoProduct(fractionalPart, scale factor (i.e. 1000.0d or 100.0d)). + * + * The below is an optimized exact "TwoProduct" calculation of passed + * fractional part with scale factor, using Ogita's Sum2S cascaded + * summation adapted as Kahan-Babuska equivalent by using FastTwoSum + * (much faster) rather than Knuth's TwoSum. + * + * We can do this because we order the summation from smallest to + * greatest, so that FastTwoSum can be used without any additional error. + * + * The "TwoProduct" exact calculation needs 17 flops. We replace this by + * a cascaded summation of FastTwoSum calculations, each involving an + * exact multiply by a power of 2. + * + * Doing so saves overall 4 multiplications and 1 addition compared to + * using traditional "TwoProduct". + * + * The scale factor is either 100 (currency case) or 1000 (decimal case). + * - when 1000, we replace it by (1024 - 16 - 8) = 1000. + * - when 100, we replace it by (128 - 32 + 4) = 100. + * Every multiplication by a power of 2 (1024, 128, 32, 16, 8, 4) is exact. + * + */ + double approxMax; // Will always be positive. + double approxMedium; // Will always be negative. + double approxMin; + + double fastTwoSumApproximation = 0.0d; + double fastTwoSumRoundOff = 0.0d; + double bVirtual = 0.0d; + + if (isCurrencyFormat) { + // Scale is 100 = 128 - 32 + 4. + // Multiply by 2**n is a shift. No roundoff. No error. + approxMax = fractionalPart * 128.00d; + approxMedium = - (fractionalPart * 32.00d); + approxMin = fractionalPart * 4.00d; + } else { + // Scale is 1000 = 1024 - 16 - 8. + // Multiply by 2**n is a shift. No roundoff. No error. + approxMax = fractionalPart * 1024.00d; + approxMedium = - (fractionalPart * 16.00d); + approxMin = - (fractionalPart * 8.00d); + } + + // Shewchuk/Dekker's FastTwoSum(approxMedium, approxMin). + assert(-approxMedium >= Math.abs(approxMin)); + fastTwoSumApproximation = approxMedium + approxMin; + bVirtual = fastTwoSumApproximation - approxMedium; + fastTwoSumRoundOff = approxMin - bVirtual; + double approxS1 = fastTwoSumApproximation; + double roundoffS1 = fastTwoSumRoundOff; + + // Shewchuk/Dekker's FastTwoSum(approxMax, approxS1); + assert(approxMax >= Math.abs(approxS1)); + fastTwoSumApproximation = approxMax + approxS1; + bVirtual = fastTwoSumApproximation - approxMax; + fastTwoSumRoundOff = approxS1 - bVirtual; + double roundoff1000 = fastTwoSumRoundOff; + double approx1000 = fastTwoSumApproximation; + double roundoffTotal = roundoffS1 + roundoff1000; + + // Shewchuk/Dekker's FastTwoSum(approx1000, roundoffTotal); + assert(approx1000 >= Math.abs(roundoffTotal)); + fastTwoSumApproximation = approx1000 + roundoffTotal; + bVirtual = fastTwoSumApproximation - approx1000; + + // Now we have got the roundoff for the scaled fractional + double scaledFractionalRoundoff = roundoffTotal - bVirtual; + + // ---- TwoProduct(fractionalPart, scale (i.e. 1000.0d or 100.0d)) end. + + /* ---- Taking the rounding decision + * + * We take rounding decision based on roundoff and half-even rounding + * rule. + * + * The above TwoProduct gives us the exact roundoff on the approximated + * scaled fractional, and we know that this approximation is exactly + * 0.5d, since that has already been tested by the caller + * (fastDoubleFormat). + * + * Decision comes first from the sign of the calculated exact roundoff. + * - Since being exact roundoff, it cannot be positive with a scaled + * fractional less than 0.5d, as well as negative with a scaled + * fractional greater than 0.5d. That leaves us with following 3 cases. + * - positive, thus scaled fractional == 0.500....0fff ==> round-up. + * - negative, thus scaled fractional == 0.499....9fff ==> don't round-up. + * - is zero, thus scaled fractioanl == 0.5 ==> half-even rounding applies : + * we round-up only if the integral part of the scaled fractional is odd. + * + */ + if (scaledFractionalRoundoff > 0.0) { + return true; + } else if (scaledFractionalRoundoff < 0.0) { + return false; + } else if ((scaledFractionalPartAsInt & 1) != 0) { + return true; + } + + return false; + + // ---- Taking the rounding decision end + } + + /** + * Collects integral digits from passed {@code number}, while setting + * grouping chars as needed. Updates {@code firstUsedIndex} accordingly. + * + * Loops downward starting from {@code backwardIndex} position (inclusive). + * + * @param number The int value from which we collect digits. + * @param digitsBuffer The char array container where digits and grouping chars + * are stored. + * @param backwardIndex the position from which we start storing digits in + * digitsBuffer. + * + */ + private void collectIntegralDigits(int number, + char[] digitsBuffer, + int backwardIndex) { + int index = backwardIndex; + int q; + int r; + while (number > 999) { + // Generates 3 digits per iteration. + q = number / 1000; + r = number - (q << 10) + (q << 4) + (q << 3); // -1024 +16 +8 = 1000. + number = q; + + digitsBuffer[index--] = DigitArrays.DigitOnes1000[r]; + digitsBuffer[index--] = DigitArrays.DigitTens1000[r]; + digitsBuffer[index--] = DigitArrays.DigitHundreds1000[r]; + digitsBuffer[index--] = fastPathData.groupingChar; + } + + // Collects last 3 or less digits. + digitsBuffer[index] = DigitArrays.DigitOnes1000[number]; + if (number > 9) { + digitsBuffer[--index] = DigitArrays.DigitTens1000[number]; + if (number > 99) + digitsBuffer[--index] = DigitArrays.DigitHundreds1000[number]; + } + + fastPathData.firstUsedIndex = index; + } + + /** + * Collects the 2 (currency) or 3 (decimal) fractional digits from passed + * {@code number}, starting at {@code startIndex} position + * inclusive. There is no punctuation to set here (no grouping chars). + * Updates {@code fastPathData.lastFreeIndex} accordingly. + * + * + * @param number The int value from which we collect digits. + * @param digitsBuffer The char array container where digits are stored. + * @param startIndex the position from which we start storing digits in + * digitsBuffer. + * + */ + private void collectFractionalDigits(int number, + char[] digitsBuffer, + int startIndex) { + int index = startIndex; + + char digitOnes = DigitArrays.DigitOnes1000[number]; + char digitTens = DigitArrays.DigitTens1000[number]; + + if (isCurrencyFormat) { + // Currency case. Always collects fractional digits. + digitsBuffer[index++] = digitTens; + digitsBuffer[index++] = digitOnes; + } else if (number != 0) { + // Decimal case. Hundreds will always be collected + digitsBuffer[index++] = DigitArrays.DigitHundreds1000[number]; + + // Ending zeros won't be collected. + if (digitOnes != '0') { + digitsBuffer[index++] = digitTens; + digitsBuffer[index++] = digitOnes; + } else if (digitTens != '0') + digitsBuffer[index++] = digitTens; + + } else + // This is decimal pattern and fractional part is zero. + // We must remove decimal point from result. + index--; + + fastPathData.lastFreeIndex = index; + } + + /** + * Internal utility. + * Adds the passed {@code prefix} and {@code suffix} to {@code container}. + * + * @param container Char array container which to prepend/append the + * prefix/suffix. + * @param prefix Char sequence to prepend as a prefix. + * @param suffix Char sequence to append as a suffix. + * + */ + // private void addAffixes(boolean isNegative, char[] container) { + private void addAffixes(char[] container, char[] prefix, char[] suffix) { + + // We add affixes only if needed (affix length > 0). + int pl = prefix.length; + int sl = suffix.length; + if (pl != 0) prependPrefix(prefix, pl, container); + if (sl != 0) appendSuffix(suffix, sl, container); + + } + + /** + * Prepends the passed {@code prefix} chars to given result + * {@code container}. Updates {@code fastPathData.firstUsedIndex} + * accordingly. + * + * @param prefix The prefix characters to prepend to result. + * @param len The number of chars to prepend. + * @param container Char array container which to prepend the prefix + */ + private void prependPrefix(char[] prefix, + int len, + char[] container) { + + fastPathData.firstUsedIndex -= len; + int startIndex = fastPathData.firstUsedIndex; + + // If prefix to prepend is only 1 char long, just assigns this char. + // If prefix is less or equal 4, we use a dedicated algorithm that + // has shown to run faster than System.arraycopy. + // If more than 4, we use System.arraycopy. + if (len == 1) + container[startIndex] = prefix[0]; + else if (len <= 4) { + int dstLower = startIndex; + int dstUpper = dstLower + len - 1; + int srcUpper = len - 1; + container[dstLower] = prefix[0]; + container[dstUpper] = prefix[srcUpper]; + + if (len > 2) + container[++dstLower] = prefix[1]; + if (len == 4) + container[--dstUpper] = prefix[2]; + } else + System.arraycopy(prefix, 0, container, startIndex, len); + } + + /** + * Appends the passed {@code suffix} chars to given result + * {@code container}. Updates {@code fastPathData.lastFreeIndex} + * accordingly. + * + * @param suffix The suffix characters to append to result. + * @param len The number of chars to append. + * @param container Char array container which to append the suffix + */ + private void appendSuffix(char[] suffix, + int len, + char[] container) { + + int startIndex = fastPathData.lastFreeIndex; + + // If suffix to append is only 1 char long, just assigns this char. + // If suffix is less or equal 4, we use a dedicated algorithm that + // has shown to run faster than System.arraycopy. + // If more than 4, we use System.arraycopy. + if (len == 1) + container[startIndex] = suffix[0]; + else if (len <= 4) { + int dstLower = startIndex; + int dstUpper = dstLower + len - 1; + int srcUpper = len - 1; + container[dstLower] = suffix[0]; + container[dstUpper] = suffix[srcUpper]; + + if (len > 2) + container[++dstLower] = suffix[1]; + if (len == 4) + container[--dstUpper] = suffix[2]; + } else + System.arraycopy(suffix, 0, container, startIndex, len); + + fastPathData.lastFreeIndex += len; + } + + /** + * Converts digit chars from {@code digitsBuffer} to current locale. + * + * Must be called before adding affixes since we refer to + * {@code fastPathData.firstUsedIndex} and {@code fastPathData.lastFreeIndex}, + * and do not support affixes (for speed reason). + * + * We loop backward starting from last used index in {@code fastPathData}. + * + * @param digitsBuffer The char array container where the digits are stored. + */ + private void localizeDigits(char[] digitsBuffer) { + + // We will localize only the digits, using the groupingSize, + // and taking into account fractional part. + + // First take into account fractional part. + int digitsCounter = + fastPathData.lastFreeIndex - fastPathData.fractionalFirstIndex; + + // The case when there is no fractional digits. + if (digitsCounter < 0) + digitsCounter = groupingSize; + + // Only the digits remains to localize. + for (int cursor = fastPathData.lastFreeIndex - 1; + cursor >= fastPathData.firstUsedIndex; + cursor--) { + if (digitsCounter != 0) { + // This is a digit char, we must localize it. + digitsBuffer[cursor] += fastPathData.zeroDelta; + digitsCounter--; + } else { + // Decimal separator or grouping char. Reinit counter only. + digitsCounter = groupingSize; + } + } + } + + /** + * This is the main entry point for the fast-path format algorithm. + * + * At this point we are sure to be in the expected conditions to run it. + * This algorithm builds the formatted result and puts it in the dedicated + * {@code fastPathData.fastPathContainer}. + * + * @param d the double value to be formatted. + * @param negative Flag precising if {@code d} is negative. + */ + private void fastDoubleFormat(double d, + boolean negative) { + + char[] container = fastPathData.fastPathContainer; + + /* + * The principle of the algorithm is to : + * - Break the passed double into its integral and fractional parts + * converted into integers. + * - Then decide if rounding up must be applied or not by following + * the half-even rounding rule, first using approximated scaled + * fractional part. + * - For the difficult cases (approximated scaled fractional part + * being exactly 0.5d), we refine the rounding decision by calling + * exactRoundUp utility method that both calculates the exact roundoff + * on the approximation and takes correct rounding decision. + * - We round-up the fractional part if needed, possibly propagating the + * rounding to integral part if we meet a "all-nine" case for the + * scaled fractional part. + * - We then collect digits from the resulting integral and fractional + * parts, also setting the required grouping chars on the fly. + * - Then we localize the collected digits if needed, and + * - Finally prepend/append prefix/suffix if any is needed. + */ + + // Exact integral part of d. + int integralPartAsInt = (int) d; + + // Exact fractional part of d (since we subtract it's integral part). + double exactFractionalPart = d - (double) integralPartAsInt; + + // Approximated scaled fractional part of d (due to multiplication). + double scaledFractional = + exactFractionalPart * fastPathData.fractionalScaleFactor; + + // Exact integral part of scaled fractional above. + int fractionalPartAsInt = (int) scaledFractional; + + // Exact fractional part of scaled fractional above. + scaledFractional = scaledFractional - (double) fractionalPartAsInt; + + // Only when scaledFractional is exactly 0.5d do we have to do exact + // calculations and take fine-grained rounding decision, since + // approximated results above may lead to incorrect decision. + // Otherwise comparing against 0.5d (strictly greater or less) is ok. + boolean roundItUp = false; + if (scaledFractional >= 0.5d) { + if (scaledFractional == 0.5d) + // Rounding need fine-grained decision. + roundItUp = exactRoundUp(exactFractionalPart, fractionalPartAsInt); + else + roundItUp = true; + + if (roundItUp) { + // Rounds up both fractional part (and also integral if needed). + if (fractionalPartAsInt < fastPathData.fractionalMaxIntBound) { + fractionalPartAsInt++; + } else { + // Propagates rounding to integral part since "all nines" case. + fractionalPartAsInt = 0; + integralPartAsInt++; + } + } + } + + // Collecting digits. + collectFractionalDigits(fractionalPartAsInt, container, + fastPathData.fractionalFirstIndex); + collectIntegralDigits(integralPartAsInt, container, + fastPathData.integralLastIndex); + + // Localizing digits. + if (fastPathData.zeroDelta != 0) + localizeDigits(container); + + // Adding prefix and suffix. + if (negative) { + if (fastPathData.negativeAffixesRequired) + addAffixes(container, + fastPathData.charsNegativePrefix, + fastPathData.charsNegativeSuffix); + } else if (fastPathData.positiveAffixesRequired) + addAffixes(container, + fastPathData.charsPositivePrefix, + fastPathData.charsPositiveSuffix); + } + + /** + * A fast-path shortcut of format(double) to be called by NumberFormat, or by + * format(double, ...) public methods. + * + * If instance can be applied fast-path and passed double is not NaN or + * Infinity, is in the integer range, we call {@code fastDoubleFormat} + * after changing {@code d} to its positive value if necessary. + * + * Otherwise returns null by convention since fast-path can't be exercized. + * + * @param d The double value to be formatted + * + * @return the formatted result for {@code d} as a string. + */ + String fastFormat(double d) { + // (Re-)Evaluates fast-path status if needed. + if (fastPathCheckNeeded) + checkAndSetFastPathStatus(); + + if (!isFastPath ) + // DecimalFormat instance is not in a fast-path state. + return null; + + if (!Double.isFinite(d)) + // Should not use fast-path for Infinity and NaN. + return null; + + // Extracts and records sign of double value, possibly changing it + // to a positive one, before calling fastDoubleFormat(). + boolean negative = false; + if (d < 0.0d) { + negative = true; + d = -d; + } else if (d == 0.0d) { + negative = (Math.copySign(1.0d, d) == -1.0d); + d = +0.0d; + } + + if (d > MAX_INT_AS_DOUBLE) + // Filters out values that are outside expected fast-path range + return null; + else + fastDoubleFormat(d, negative); + + // Returns a new string from updated fastPathContainer. + return new String(fastPathData.fastPathContainer, + fastPathData.firstUsedIndex, + fastPathData.lastFreeIndex - fastPathData.firstUsedIndex); + + } + + // ======== End fast-path formating logic for double ========================= + /** * Complete the formatting of a finite number. On entry, the digitList must * be filled in with the correct digits. @@ -1168,8 +1898,7 @@ if (isNegative) { append(result, negativeSuffix, delegate, getNegativeSuffixFieldPositions(), Field.SIGN); - } - else { + } else { append(result, positiveSuffix, delegate, getPositiveSuffixFieldPositions(), Field.SIGN); } @@ -1557,8 +2286,7 @@ sawExponent = true; } break; // Whether we fail or succeed, we exit this loop - } - else { + } else { break; } } @@ -1653,6 +2381,7 @@ // don't allow multiple references symbols = (DecimalFormatSymbols) newSymbols.clone(); expandAffixes(); + fastPathCheckNeeded = true; } catch (Exception foo) { // should never happen } @@ -1674,6 +2403,7 @@ positivePrefix = newValue; posPrefixPattern = null; positivePrefixFieldPositions = null; + fastPathCheckNeeded = true; } /** @@ -1688,8 +2418,7 @@ if (positivePrefixFieldPositions == null) { if (posPrefixPattern != null) { positivePrefixFieldPositions = expandAffix(posPrefixPattern); - } - else { + } else { positivePrefixFieldPositions = EmptyFieldPositionArray; } } @@ -1711,6 +2440,7 @@ public void setNegativePrefix (String newValue) { negativePrefix = newValue; negPrefixPattern = null; + fastPathCheckNeeded = true; } /** @@ -1725,8 +2455,7 @@ if (negativePrefixFieldPositions == null) { if (negPrefixPattern != null) { negativePrefixFieldPositions = expandAffix(negPrefixPattern); - } - else { + } else { negativePrefixFieldPositions = EmptyFieldPositionArray; } } @@ -1748,6 +2477,7 @@ public void setPositiveSuffix (String newValue) { positiveSuffix = newValue; posSuffixPattern = null; + fastPathCheckNeeded = true; } /** @@ -1762,8 +2492,7 @@ if (positiveSuffixFieldPositions == null) { if (posSuffixPattern != null) { positiveSuffixFieldPositions = expandAffix(posSuffixPattern); - } - else { + } else { positiveSuffixFieldPositions = EmptyFieldPositionArray; } } @@ -1785,6 +2514,7 @@ public void setNegativeSuffix (String newValue) { negativeSuffix = newValue; negSuffixPattern = null; + fastPathCheckNeeded = true; } /** @@ -1799,8 +2529,7 @@ if (negativeSuffixFieldPositions == null) { if (negSuffixPattern != null) { negativeSuffixFieldPositions = expandAffix(negSuffixPattern); - } - else { + } else { negativeSuffixFieldPositions = EmptyFieldPositionArray; } } @@ -1834,6 +2563,16 @@ multiplier = newValue; bigDecimalMultiplier = null; bigIntegerMultiplier = null; + fastPathCheckNeeded = true; + } + + /** + * {@inheritDoc} + */ + @Override + public void setGroupingUsed(boolean newValue) { + super.setGroupingUsed(newValue); + fastPathCheckNeeded = true; } /** @@ -1860,6 +2599,7 @@ */ public void setGroupingSize (int newValue) { groupingSize = (byte)newValue; + fastPathCheckNeeded = true; } /** @@ -1878,6 +2618,7 @@ */ public void setDecimalSeparatorAlwaysShown(boolean newValue) { decimalSeparatorAlwaysShown = newValue; + fastPathCheckNeeded = true; } /** @@ -1908,6 +2649,20 @@ DecimalFormat other = (DecimalFormat) super.clone(); other.symbols = (DecimalFormatSymbols) symbols.clone(); other.digitList = (DigitList) digitList.clone(); + + // Fast-path is almost stateless algorithm. The only logical state is the + // isFastPath flag. In addition fastPathCheckNeeded is a sentinel flag + // that forces recalculation of all fast-path fields when set to true. + // + // There is thus no need to clone all the fast-path fields. + // We just only need to set fastPathCheckNeeded to true when cloning, + // and init fastPathData to null as if it were a truly new instance. + // Every fast-path field will be recalculated (only once) at next usage of + // fast-path algorithm. + other.fastPathCheckNeeded = true; + other.isFastPath = false; + other.fastPathData = null; + return other; } @@ -1917,8 +2672,10 @@ @Override public boolean equals(Object obj) { - if (obj == null) return false; - if (!super.equals(obj)) return false; // super does class check + if (obj == null) + return false; + if (!super.equals(obj)) + return false; // super does class check DecimalFormat other = (DecimalFormat) obj; return ((posPrefixPattern == other.posPrefixPattern && positivePrefix.equals(other.positivePrefix)) @@ -2206,8 +2963,7 @@ || affix.indexOf(symbols.getPatternSeparator()) >= 0 || affix.indexOf(symbols.getMinusSign()) >= 0 || affix.indexOf(CURRENCY_SIGN) >= 0; - } - else { + } else { needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0 @@ -2694,6 +3450,7 @@ super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); } + fastPathCheckNeeded = true; } /** @@ -2714,6 +3471,7 @@ super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); } + fastPathCheckNeeded = true; } /** @@ -2734,6 +3492,7 @@ super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS : minimumFractionDigits); } + fastPathCheckNeeded = true; } /** @@ -2754,6 +3513,7 @@ super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS : maximumFractionDigits); } + fastPathCheckNeeded = true; } /** @@ -2843,6 +3603,7 @@ expandAffixes(); } } + fastPathCheckNeeded = true; } /** @@ -2873,6 +3634,7 @@ this.roundingMode = roundingMode; digitList.setRoundingMode(roundingMode); + fastPathCheckNeeded = true; } /** @@ -2924,9 +3686,18 @@ stream.defaultReadObject(); digitList = new DigitList(); + // We force complete fast-path reinitialization when the instance is + // deserialized. See clone() comment on fastPathCheckNeeded. + fastPathCheckNeeded = true; + isFastPath = false; + fastPathData = null; + if (serialVersionOnStream < 4) { setRoundingMode(RoundingMode.HALF_EVEN); + } else { + setRoundingMode(getRoundingMode()); } + // We only need to check the maximum counts because NumberFormat // .readObject has already ensured that the maximum is greater than the // minimum count. @@ -3195,6 +3966,77 @@ */ private RoundingMode roundingMode = RoundingMode.HALF_EVEN; + // ------ DecimalFormat fields for fast-path for double algorithm ------ + + /** + * Helper inner utility class for storing the data used in the fast-path + * algorithm. Almost all fields related to fast-path are encapsulated in + * this class. + * + * Any {@code DecimalFormat} instance has a {@code fastPathData} + * reference field that is null unless both the properties of the instance + * are such that the instance is in the "fast-path" state, and a format call + * has been done at least once while in this state. + * + * Almost all fields are related to the "fast-path" state only and don't + * change until one of the instance properties is changed. + * + * {@code firstUsedIndex} and {@code lastFreeIndex} are the only + * two fields that are used and modified while inside a call to + * {@code fastDoubleFormat}. + * + */ + private static class FastPathData { + // --- Temporary fields used in fast-path, shared by several methods. + + /** The first unused index at the end of the formatted result. */ + int lastFreeIndex; + + /** The first used index at the beginning of the formatted result */ + int firstUsedIndex; + + // --- State fields related to fast-path status. Changes due to a + // property change only. Set by checkAndSetFastPathStatus() only. + + /** Difference between locale zero and default zero representation. */ + int zeroDelta; + + /** Locale char for grouping separator. */ + char groupingChar; + + /** Fixed index position of last integral digit of formatted result */ + int integralLastIndex; + + /** Fixed index position of first fractional digit of formatted result */ + int fractionalFirstIndex; + + /** Fractional constants depending on decimal|currency state */ + double fractionalScaleFactor; + int fractionalMaxIntBound; + + + /** The char array buffer that will contain the formatted result */ + char[] fastPathContainer; + + /** Suffixes recorded as char array for efficiency. */ + char[] charsPositivePrefix; + char[] charsNegativePrefix; + char[] charsPositiveSuffix; + char[] charsNegativeSuffix; + boolean positiveAffixesRequired = true; + boolean negativeAffixesRequired = true; + } + + /** The format fast-path status of the instance. Logical state. */ + private transient boolean isFastPath = false; + + /** Flag stating need of check and reinit fast-path status on next format call. */ + private transient boolean fastPathCheckNeeded = true; + + /** DecimalFormat reference to its FastPathData */ + private transient FastPathData fastPathData; + + //---------------------------------------------------------------------- static final int currentSerialVersion = 4; @@ -3228,6 +4070,54 @@ // CONSTANTS //---------------------------------------------------------------------- + // ------ Fast-Path for double Constants ------ + + /** Maximum valid integer value for applying fast-path algorithm */ + private static final double MAX_INT_AS_DOUBLE = (double) Integer.MAX_VALUE; + + /** + * The digit arrays used in the fast-path methods for collecting digits. + * Using 3 constants arrays of chars ensures a very fast collection of digits + */ + private static class DigitArrays { + static final char[] DigitOnes1000 = new char[1000]; + static final char[] DigitTens1000 = new char[1000]; + static final char[] DigitHundreds1000 = new char[1000]; + + // initialize on demand holder class idiom for arrays of digits + static { + int tenIndex = 0; + int hundredIndex = 0; + char digitOne = '0'; + char digitTen = '0'; + char digitHundred = '0'; + for (int i = 0; i < 1000; i++ ) { + + DigitOnes1000[i] = digitOne; + if (digitOne == '9') + digitOne = '0'; + else + digitOne++; + + DigitTens1000[i] = digitTen; + if (i == (tenIndex + 9)) { + tenIndex += 10; + if (digitTen == '9') + digitTen = '0'; + else + digitTen++; + } + + DigitHundreds1000[i] = digitHundred; + if (i == (hundredIndex + 99)) { + digitHundred++; + hundredIndex += 100; + } + } + } + } + // ------ Fast-Path for double Constants end ------ + // Constants for characters used in programmatic (unlocalized) patterns. private static final char PATTERN_ZERO_DIGIT = '0'; private static final char PATTERN_GROUPING_SEPARATOR = ',';
--- a/src/share/classes/java/text/DigitList.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/DigitList.java Thu Oct 11 16:59:50 2012 -0700 @@ -62,7 +62,7 @@ * derived by placing all the digits of the list to the right of the * decimal point, by 10^exponent. * - * @see Locale + * @see java.util.Locale * @see Format * @see NumberFormat * @see DecimalFormat
--- a/src/share/classes/java/text/Format.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/Format.java Thu Oct 11 16:59:50 2012 -0700 @@ -370,7 +370,7 @@ * Delegates should NOT assume that the <code>Format</code> will notify * the delegate of fields in any particular order. * - * @see FieldPosition.Delegate + * @see FieldPosition#getFieldDelegate * @see CharacterIteratorFieldDelegate */ interface FieldDelegate {
--- a/src/share/classes/java/text/NumberFormat.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/NumberFormat.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -286,10 +286,21 @@ * @see java.text.Format#format */ public final String format(double number) { + // Use fast-path for double result if that works + String result = fastFormat(number); + if (result != null) + return result; + return format(number, new StringBuffer(), DontCareFieldPosition.INSTANCE).toString(); } + /* + * fastFormat() is supposed to be implemented in concrete subclasses only. + * Default implem always returns null. + */ + String fastFormat(double number) { return null; } + /** * Specialization of format. * @exception ArithmeticException if rounding is needed with rounding
--- a/src/share/classes/java/text/RBCollationTables.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/RBCollationTables.java Thu Oct 11 16:59:50 2012 -0700 @@ -192,13 +192,12 @@ * * @see CollationElementIterator#getMaxExpansion */ - int getMaxExpansion(int order) - { + int getMaxExpansion(int order) { int result = 1; if (expandTable != null) { // Right now this does a linear search through the entire - // expandsion table. If a collator had a large number of expansions, + // expansion table. If a collator had a large number of expansions, // this could cause a performance problem, but in practise that // rarely happens for (int i = 0; i < expandTable.size(); i++) { @@ -215,20 +214,19 @@ } /** - * Get the entry of hash table of the expanding string in the collation - * table. - * @param idx the index of the expanding string value list + * Get the entry of hash table of the expanding string in the collation + * table. + * @param idx the index of the expanding string value list */ - final int[] getExpandValueList(int order) { - return expandTable.elementAt(order - EXPANDCHARINDEX); + final int[] getExpandValueList(int idx) { + return expandTable.elementAt(idx - EXPANDCHARINDEX); } /** - * Get the comarison order of a character from the collation table. - * @return the comparison order of a character. + * Get the comarison order of a character from the collation table. + * @return the comparison order of a character. */ - int getUnicodeOrder(int ch) - { + int getUnicodeOrder(int ch) { return mapping.elementAt(ch); }
--- a/src/share/classes/java/text/RBTableBuilder.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/RBTableBuilder.java Thu Oct 11 16:59:50 2012 -0700 @@ -71,7 +71,7 @@ * This is the main function that actually builds the tables and * stores them back in the RBCollationTables object. It is called * ONLY by the RBCollationTables constructor. - * @see java.util.RuleBasedCollator#RuleBasedCollator + * @see RuleBasedCollator#RuleBasedCollator * @exception ParseException If the rules format is incorrect. */
--- a/src/share/classes/java/text/SimpleDateFormat.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/text/SimpleDateFormat.java Thu Oct 11 16:59:50 2012 -0700 @@ -1787,7 +1787,7 @@ * timeFields. Returns -start (for ParsePosition) if failed. * @param text the time text to be parsed. * @param start where to start parsing. - * @param ch the pattern character for the date field text to be parsed. + * @param patternCharIndex the index of the pattern character. * @param count the count of a pattern character. * @param obeyCount if true, then the next field directly abuts this one, * and we should use the count to know when to stop parsing.
--- a/src/share/classes/java/util/Calendar.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/Calendar.java Thu Oct 11 16:59:50 2012 -0700 @@ -1788,7 +1788,6 @@ * * @return a bit mask of selected fields * @see #isExternallySet(int) - * @see #setInternallySetState(int) */ final int selectFields() { // This implementation has been taken from the GregorianCalendar class.
--- a/src/share/classes/java/util/Currency.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/Currency.java Thu Oct 11 16:59:50 2012 -0700 @@ -665,7 +665,7 @@ * * @param pattern regex pattern for the properties * @param ctry country code - * @param data currency data. This is a comma separated string that + * @param curdata currency data. This is a comma separated string that * consists of "three-letter alphabet code", "three-digit numeric code", * and "one-digit (0,1,2, or 3) default fraction digit". * For example, "JPZ,392,0".
--- a/src/share/classes/java/util/Formatter.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/Formatter.java Thu Oct 11 16:59:50 2012 -0700 @@ -918,7 +918,7 @@ * <p> If the {@code '0'} flag is given then the output will be padded * with leading zeros to the field width following any indication of sign. * - * <p> If {@code '('}, {@code '+'}, '  ', or {@code ','} flags + * <p> If {@code '('}, {@code '+'}, ' ', or {@code ','} flags * are given then a {@link FormatFlagsConversionMismatchException} will be * thrown. *
--- a/src/share/classes/java/util/JapaneseImperialCalendar.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/JapaneseImperialCalendar.java Thu Oct 11 16:59:50 2012 -0700 @@ -1932,7 +1932,7 @@ * Computes the fixed date under either the Gregorian or the * Julian calendar, using the given year and the specified calendar fields. * - * @param cal the CalendarSystem to be used for the date calculation + * @param era era index * @param year the normalized year number, with 0 indicating the * year 1 BCE, -1 indicating 2 BCE, etc. * @param fieldMask the calendar fields to be used for the date calculation @@ -2141,7 +2141,7 @@ * Returns the length of the specified month in the specified * Gregorian year. The year number must be normalized. * - * @see #isLeapYear(int) + * @see GregorianCalendar#isLeapYear(int) */ private int monthLength(int month, int gregorianYear) { return CalendarUtils.isGregorianLeapYear(gregorianYear) ? @@ -2152,7 +2152,7 @@ * Returns the length of the specified month in the year provided * by internalGet(YEAR). * - * @see #isLeapYear(int) + * @see GregorianCalendar#isLeapYear(int) */ private int monthLength(int month) { assert jdate.isNormalized();
--- a/src/share/classes/java/util/JumboEnumSet.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/JumboEnumSet.java Thu Oct 11 16:59:50 2012 -0700 @@ -345,7 +345,7 @@ * the same size, and every member of the given set is contained in * this set. * - * @param e object to be compared for equality with this set + * @param o object to be compared for equality with this set * @return <tt>true</tt> if the specified object is equal to this set */ public boolean equals(Object o) {
--- a/src/share/classes/java/util/Locale.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/Locale.java Thu Oct 11 16:59:50 2012 -0700 @@ -55,6 +55,7 @@ import sun.util.locale.InternalLocaleBuilder; import sun.util.locale.LanguageTag; import sun.util.locale.LocaleExtensions; +import sun.util.locale.LocaleMatcher; import sun.util.locale.LocaleObjectCache; import sun.util.locale.LocaleSyntaxException; import sun.util.locale.LocaleUtils; @@ -71,10 +72,11 @@ * according to the customs and conventions of the user's native country, * region, or culture. * - * <p> The <code>Locale</code> class implements identifiers - * interchangeable with BCP 47 (IETF BCP 47, "Tags for Identifying - * Languages"), with support for the LDML (UTS#35, "Unicode Locale - * Data Markup Language") BCP 47-compatible extensions for locale data + * <p> The {@code Locale} class implements IETF BCP 47 which is composed of + * <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 "Matching of Language + * Tags"</a> and <a href="http://tools.ietf.org/html/rfc5646">RFC 5646 "Tags + * for Identifying Languages"</a> with support for the LDML (UTS#35, "Unicode + * Locale Data Markup Language") BCP 47-compatible extensions for locale data * exchange. * * <p> A <code>Locale</code> object logically consists of the fields @@ -267,6 +269,77 @@ * </pre> * </blockquote> * + * <h4><a name="LocaleMatching">Locale Matching</a></h4> + * + * <p>If an application or a system is internationalized and provides localized + * resources for multiple locales, it sometimes needs to find one or more + * locales (or language tags) which meet each user's specific preferences. Note + * that a term "language tag" is used interchangeably with "locale" in this + * locale matching documentation. + * + * <p>In order to do matching a user's preferred locales to a set of language + * tags, <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 Matching of + * Language Tags</a> defines two mechanisms: filtering and lookup. + * <em>Filtering</em> is used to get all matching locales, whereas + * <em>lookup</em> is to choose the best matching locale. + * Matching is done case-insensitively. These matching mechanisms are described + * in the following sections. + * + * <p>A user's preference is called a <em>Language Priority List</em> and is + * expressed as a list of language ranges. There are syntactically two types of + * language ranges: basic and extended. See + * {@link Locale.LanguageRange Locale.LanguageRange} for details. + * + * <h5>Filtering</h5> + * + * <p>The filtering operation returns all matching language tags. It is defined + * in RFC 4647 as follows: + * "In filtering, each language range represents the least specific language + * tag (that is, the language tag with fewest number of subtags) that is an + * acceptable match. All of the language tags in the matching set of tags will + * have an equal or greater number of subtags than the language range. Every + * non-wildcard subtag in the language range will appear in every one of the + * matching language tags." + * + * <p>There are two types of filtering: filtering for basic language ranges + * (called "basic filtering") and filtering for extended language ranges + * (called "extended filtering"). They may return different results by what + * kind of language ranges are included in the given Language Priority List. + * {@link Locale.FilteringMode} is a parameter to specify how filtering should + * be done. + * + * <h5>Lookup</h5> + * + * <p>The lookup operation returns the best matching language tags. It is + * defined in RFC 4647 as follows: + * "By contrast with filtering, each language range represents the most + * specific tag that is an acceptable match. The first matching tag found, + * according to the user's priority, is considered the closest match and is the + * item returned." + * + * <p>For example, if a Language Priority List consists of two language ranges, + * {@code "zh-Hant-TW"} and {@code "en-US"}, in prioritized order, lookup + * method progressively searches the language tags below in order to find the + * best matching language tag. + * <blockquote> + * <pre> + * 1. zh-Hant-TW + * 2. zh-Hant + * 3. zh + * 4. en-US + * 5. en + * </pre> + * </blockquote> + * If there is a language tag which matches completely to a language range + * above, the language tag is returned. + * + * <p>{@code "*"} is the special language range, and it is ignored in lookup. + * + * <p>If multiple language tags match as a result of the subtag {@code '*'} + * included in a language range, the first matching language tag returned by + * an {@link Iterator} over a {@link Collection} of language tags is treated as + * the best matching one. + * * <h4>Use of Locale</h4> * * <p>Once you've created a <code>Locale</code> you can query it for information @@ -1419,7 +1492,7 @@ * // returns "ja-JP-u-ca-japanese-x-lvariant-JP" * Locale.forLanguageTag("th-TH-x-lvariant-TH").toLanguageTag(); * // returns "th-TH-u-nu-thai-x-lvariant-TH" - * <pre></ul> + * </pre></ul> * * <p>This implements the 'Language-Tag' production of BCP47, and * so supports grandfathered (regular and irregular) as well as @@ -2070,7 +2143,7 @@ * @param in the <code>ObjectInputStream</code> to read * @throws IOException * @throws ClassNotFoundException - * @throws IllformdLocaleException + * @throws IllformedLocaleException * @since 1.7 */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { @@ -2574,4 +2647,611 @@ return Locale.getInstance(baseloc, extensions); } } + + /** + * This enum provides constants to select a filtering mode for locale + * matching. Refer to <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 + * Matching of Language Tags</a> for details. + * + * <p>As an example, think of two Language Priority Lists each of which + * includes only one language range and a set of following language tags: + * + * <pre> + * de (German) + * de-DE (German, Germany) + * de-Deva (German, in Devanagari script) + * de-Deva-DE (German, in Devanagari script, Germany) + * de-DE-1996 (German, Germany, orthography of 1996) + * de-Latn-DE (German, in Latin script, Germany) + * de-Latn-DE-1996 (German, in Latin script, Germany, orthography of 1996) + * </pre> + * + * The filtering method will behave as follows: + * + * <table cellpadding=2> + * <tr> + * <th>Filtering Mode</th> + * <th>Language Priority List: {@code "de-DE"}</th> + * <th>Language Priority List: {@code "de-*-DE"}</th> + * </tr> + * <tr> + * <td valign=top> + * {@link FilteringMode#AUTOSELECT_FILTERING AUTOSELECT_FILTERING} + * </td> + * <td valign=top> + * Performs <em>basic</em> filtering and returns {@code "de-DE"} and + * {@code "de-DE-1996"}. + * </td> + * <td valign=top> + * Performs <em>extended</em> filtering and returns {@code "de-DE"}, + * {@code "de-Deva-DE"}, {@code "de-DE-1996"}, {@code "de-Latn-DE"}, and + * {@code "de-Latn-DE-1996"}. + * </td> + * </tr> + * <tr> + * <td valign=top> + * {@link FilteringMode#EXTENDED_FILTERING EXTENDED_FILTERING} + * </td> + * <td valign=top> + * Performs <em>extended</em> filtering and returns {@code "de-DE"}, + * {@code "de-Deva-DE"}, {@code "de-DE-1996"}, {@code "de-Latn-DE"}, and + * {@code "de-Latn-DE-1996"}. + * </td> + * <td valign=top>Same as above.</td> + * </tr> + * <tr> + * <td valign=top> + * {@link FilteringMode#IGNORE_EXTENDED_RANGES IGNORE_EXTENDED_RANGES} + * </td> + * <td valign=top> + * Performs <em>basic</em> filtering and returns {@code "de-DE"} and + * {@code "de-DE-1996"}. + * </td> + * <td valign=top> + * Performs <em>basic</em> filtering and returns {@code null} because + * nothing matches. + * </td> + * </tr> + * <tr> + * <td valign=top> + * {@link FilteringMode#MAP_EXTENDED_RANGES MAP_EXTENDED_RANGES} + * </td> + * <td valign=top>Same as above.</td> + * <td valign=top> + * Performs <em>basic</em> filtering and returns {@code "de-DE"} and + * {@code "de-DE-1996"} because {@code "de-*-DE"} is mapped to + * {@code "de-DE"}. + * </td> + * </tr> + * <tr> + * <td valign=top> + * {@link FilteringMode#REJECT_EXTENDED_RANGES REJECT_EXTENDED_RANGES} + * </td> + * <td valign=top>Same as above.</td> + * <td valign=top> + * Throws {@link IllegalArgumentException} because {@code "de-*-DE"} is + * not a valid basic language range. + * </td> + * </tr> + * </table> + * + * @see #filter(List, Collection, FilteringMode) + * @see #filterTags(List, Collection, FilteringMode) + * + * @since 1.8 + */ + public static enum FilteringMode { + /** + * Specifies automatic filtering mode based on the given Language + * Priority List consisting of language ranges. If all of the ranges + * are basic, basic filtering is selected. Otherwise, extended + * filtering is selected. + */ + AUTOSELECT_FILTERING, + + /** + * Specifies extended filtering. + */ + EXTENDED_FILTERING, + + /** + * Specifies basic filtering: Note that any extended language ranges + * included in the given Language Priority List are ignored. + */ + IGNORE_EXTENDED_RANGES, + + /** + * Specifies basic filtering: If any extended language ranges are + * included in the given Language Priority List, they are mapped to the + * basic language range. Specifically, a language range starting with a + * subtag {@code "*"} is treated as a language range {@code "*"}. For + * example, {@code "*-US"} is treated as {@code "*"}. If {@code "*"} is + * not the first subtag, {@code "*"} and extra {@code "-"} are removed. + * For example, {@code "ja-*-JP"} is mapped to {@code "ja-JP"}. + */ + MAP_EXTENDED_RANGES, + + /** + * Specifies basic filtering: If any extended language ranges are + * included in the given Language Priority List, the list is rejected + * and the filtering method throws {@link IllegalArgumentException}. + */ + REJECT_EXTENDED_RANGES + }; + + /** + * This class expresses a <em>Language Range</em> defined in + * <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 Matching of + * Language Tags</a>. A language range is an identifier which is used to + * select language tag(s) meeting specific requirements by using the + * mechanisms described in <a href="Locale.html#LocaleMatching">Locale + * Matching</a>. A list which represents a user's preferences and consists + * of language ranges is called a <em>Language Priority List</em>. + * + * <p>There are two types of language ranges: basic and extended. In RFC + * 4647, the syntax of language ranges is expressed in + * <a href="http://tools.ietf.org/html/rfc4234">ABNF</a> as follows: + * <blockquote> + * <pre> + * basic-language-range = (1*8ALPHA *("-" 1*8alphanum)) / "*" + * extended-language-range = (1*8ALPHA / "*") + * *("-" (1*8alphanum / "*")) + * alphanum = ALPHA / DIGIT + * </pre> + * </blockquote> + * For example, {@code "en"} (English), {@code "ja-JP"} (Japanese, Japan), + * {@code "*"} (special language range which matches any language tag) are + * basic language ranges, whereas {@code "*-CH"} (any languages, + * Switzerland), {@code "es-*"} (Spanish, any regions), and + * {@code "zh-Hant-*"} (Traditional Chinese, any regions) are extended + * language ranges. + * + * @see #filter + * @see #filterTags + * @see #lookup + * @see #lookupTag + * + * @since 1.8 + */ + public static final class LanguageRange { + + /** + * A constant holding the maximum value of weight, 1.0, which indicates + * that the language range is a good fit for the user. + */ + public static final double MAX_WEIGHT = 1.0; + + /** + * A constant holding the minimum value of weight, 0.0, which indicates + * that the language range is not a good fit for the user. + */ + public static final double MIN_WEIGHT = 0.0; + + private final String range; + private final double weight; + + private volatile int hash = 0; + + /** + * Constructs a {@code LanguageRange} using the given {@code range}. + * Note that no validation is done against the IANA Language Subtag + * Registry at time of construction. + * + * <p>This is equivalent to {@code LanguageRange(range, MAX_WEIGHT)}. + * + * @param range a language range + * @throws NullPointerException if the given {@code range} is + * {@code null} + */ + public LanguageRange(String range) { + this(range, MAX_WEIGHT); + } + + /** + * Constructs a {@code LanguageRange} using the given {@code range} and + * {@code weight}. Note that no validation is done against the IANA + * Language Subtag Registry at time of construction. + * + * @param range a language range + * @param weight a weight value between {@code MIN_WEIGHT} and + * {@code MAX_WEIGHT} + * @throws NullPointerException if the given {@code range} is + * {@code null} + * @throws IllegalArgumentException if the given {@code weight} is less + * than {@code MIN_WEIGHT} or greater than {@code MAX_WEIGHT} + */ + public LanguageRange(String range, double weight) { + if (range == null) { + throw new NullPointerException(); + } + if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) { + throw new IllegalArgumentException("weight=" + weight); + } + + range = range.toLowerCase(); + + // Do syntax check. + boolean isIllFormed = false; + String[] subtags = range.split("-"); + if (isSubtagIllFormed(subtags[0], true) + || range.endsWith("-")) { + isIllFormed = true; + } else { + for (int i = 1; i < subtags.length; i++) { + if (isSubtagIllFormed(subtags[i], false)) { + isIllFormed = true; + } + break; + } + } + if (isIllFormed) { + throw new IllegalArgumentException("range=" + range); + } + + this.range = range; + this.weight = weight; + } + + private static boolean isSubtagIllFormed(String subtag, + boolean isFirstSubtag) { + if (subtag.equals("") || subtag.length() > 8) { + return true; + } else if (subtag.equals("*")) { + return false; + } + char[] charArray = subtag.toCharArray(); + if (isFirstSubtag) { // ALPHA + for (char c : charArray) { + if (c < 'a' || c > 'z') { + return true; + } + } + } else { // ALPHA / DIGIT + for (char c : charArray) { + if (c < '0' || (c > '9' && c < 'a') || c > 'z') { + return true; + } + } + } + return false; + } + + /** + * Returns the language range of this {@code LanguageRange}. + * + * @return the language range. + */ + public String getRange() { + return range; + } + + /** + * Returns the weight of this {@code LanguageRange}. + * + * @return the weight value. + */ + public double getWeight() { + return weight; + } + + /** + * Parses the given {@code ranges} to generate a Language Priority List. + * + * <p>This method performs a syntactic check for each language range in + * the given {@code ranges} but doesn't do validation using the IANA + * Language Subtag Registry. + * + * <p>The {@code ranges} to be given can take one of the following + * forms: + * + * <pre> + * "Accept-Language: ja,en;q=0.4" (weighted list with Accept-Language prefix) + * "ja,en;q=0.4" (weighted list) + * "ja,en" (prioritized list) + * </pre> + * + * In a weighted list, each language range is given a weight value. + * The weight value is identical to the "quality value" in + * <a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>, and it + * expresses how much the user prefers the language. A weight value is + * specified after a corresponding language range followed by + * {@code ";q="}, and the default weight value is {@code MAX_WEIGHT} + * when it is omitted. + * + * <p>Unlike a weighted list, language ranges in a prioritized list + * are sorted in the descending order based on its priority. The first + * language range has the highest priority and meets the user's + * preference most. + * + * <p>In either case, language ranges are sorted in descending order in + * the Language Priority List based on priority or weight. If a + * language range appears in the given {@code ranges} more than once, + * only the first one is included on the Language Priority List. + * + * <p>The returned list consists of language ranges from the given + * {@code ranges} and their equivalents found in the IANA Language + * Subtag Registry. For example, if the given {@code ranges} is + * {@code "Accept-Language: iw,en-us;q=0.7,en;q=0.3"}, the elements in + * the list to be returned are: + * + * <pre> + * <b>Range</b> <b>Weight</b> + * "iw" (older tag for Hebrew) 1.0 + * "he" (new preferred code for Hebrew) 1.0 + * "en-us" (English, United States) 0.7 + * "en" (English) 0.3 + * </pre> + * + * Two language ranges, {@code "iw"} and {@code "he"}, have the same + * highest priority in the list. By adding {@code "he"} to the user's + * Language Priority List, locale-matching method can find Hebrew as a + * matching locale (or language tag) even if the application or system + * offers only {@code "he"} as a supported locale (or language tag). + * + * @param ranges a list of comma-separated language ranges or a list of + * language ranges in the form of the "Accept-Language" header + * defined in <a href="http://tools.ietf.org/html/rfc2616">RFC + * 2616</a> + * @return a Language Priority List consisting of language ranges + * included in the given {@code ranges} and their equivalent + * language ranges if available. The list is modifiable. + * @throws NullPointerException if {@code ranges} is null + * @throws IllegalArgumentException if a language range or a weight + * found in the given {@code ranges} is ill-formed + */ + public static List<LanguageRange> parse(String ranges) { + return LocaleMatcher.parse(ranges); + } + + /** + * Parses the given {@code ranges} to generate a Language Priority + * List, and then customizes the list using the given {@code map}. + * This method is equivalent to + * {@code mapEquivalents(parse(ranges), map)}. + * + * @param ranges a list of comma-separated language ranges or a list + * of language ranges in the form of the "Accept-Language" header + * defined in <a href="http://tools.ietf.org/html/rfc2616">RFC + * 2616</a> + * @param map a map containing information to customize language ranges + * @return a Language Priority List with customization. The list is + * @throws NullPointerException if {@code ranges} is null + * @throws IllegalArgumentException if a language range or a weight + * found in the given {@code ranges} is ill-formed + * @see #parse(String) + * @see #mapEquivalents + */ + public static List<LanguageRange> parse(String ranges, + Map<String, List<String>> map) { + return mapEquivalents(parse(ranges), map); + } + + /** + * Generates a new customized Language Priority List using the given + * {@code priorityList} and {@code map}. If the given {@code map} is + * empty, this method returns a copy of the given {@code priorityList}. + * + * <p>In the map, a key represents a language range whereas a value is + * a list of equivalents of it. {@code '*'} cannot be used in the map. + * Each equivalent language range has the same weight value as its + * original language range. + * + * <pre> + * An example of map: + * <b>Key</b> <b>Value</b> + * "zh" (Chinese) "zh", + * "zh-Hans"(Simplified Chinese) + * "zh-HK" (Chinese, Hong Kong) "zh-HK" + * "zh-TW" (Chinese, Taiwan) "zh-TW" + * </pre> + * + * The customization is performed after modification using the IANA + * Language Subtag Registry. + * + * <p>For example, if a user's Language Priority List consists of five + * language ranges ({@code "zh"}, {@code "zh-CN"}, {@code "en"}, + * {@code "zh-TW"}, and {@code "zh-HK"}), the newly generated Language + * Priority List which is customized using the above map example will + * consists of {@code "zh"}, {@code "zh-Hans"}, {@code "zh-CN"}, + * {@code "zh-Hans-CN"}, {@code "en"}, {@code "zh-TW"}, and + * {@code "zh-HK"}. + * + * <p>{@code "zh-HK"} and {@code "zh-TW"} aren't converted to + * {@code "zh-Hans-HK"} nor {@code "zh-Hans-TW"} even if they are + * included in the Language Priority List. In this example, mapping + * is used to clearly distinguish Simplified Chinese and Traditional + * Chinese. + * + * <p>If the {@code "zh"}-to-{@code "zh"} mapping isn't included in the + * map, a simple replacement will be performed and the customized list + * won't include {@code "zh"} and {@code "zh-CN"}. + * + * @param priorityList user's Language Priority List + * @param map a map containing information to customize language ranges + * @return a new Language Priority List with customization. The list is + * modifiable. + * @throws NullPointerException if {@code priorityList} is {@code null} + * @see #parse(String, Map) + */ + public static List<LanguageRange> mapEquivalents( + List<LanguageRange>priorityList, + Map<String, List<String>> map) { + return LocaleMatcher.mapEquivalents(priorityList, map); + } + + /** + * Returns a hash code value for the object. + * + * @return a hash code value for this object. + */ + @Override + public int hashCode() { + if (hash == 0) { + int result = 17; + result = 37*result + range.hashCode(); + long bitsWeight = Double.doubleToLongBits(weight); + result = 37*result + (int)(bitsWeight ^ (bitsWeight >>> 32)); + hash = result; + } + return hash; + } + + /** + * Compares this object to the specified object. The result is true if + * and only if the argument is not {@code null} and is a + * {@code LanguageRange} object that contains the same {@code range} + * and {@code weight} values as this object. + * + * @param obj the object to compare with + * @return {@code true} if this object's {@code range} and + * {@code weight} are the same as the {@code obj}'s; {@code false} + * otherwise. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof LanguageRange)) { + return false; + } + LanguageRange other = (LanguageRange)obj; + return hash == other.hash + && range.equals(other.range) + && weight == other.weight; + } + } + + /** + * Returns a list of matching {@code Locale} instances using the filtering + * mechanism defined in RFC 4647. + * + * @param priorityList user's Language Priority List in which each language + * tag is sorted in descending order based on priority or weight + * @param locales {@code Locale} instances used for matching + * @param mode filtering mode + * @return a list of {@code Locale} instances for matching language tags + * sorted in descending order based on priority or weight, or an empty + * list if nothing matches. The list is modifiable. + * @throws NullPointerException if {@code priorityList} or {@code locales} + * is {@code null} + * @throws IllegalArgumentException if one or more extended language ranges + * are included in the given list when + * {@link FilteringMode#REJECT_EXTENDED_RANGES} is specified + * + * @since 1.8 + */ + public static List<Locale> filter(List<LanguageRange> priorityList, + Collection<Locale> locales, + FilteringMode mode) { + return LocaleMatcher.filter(priorityList, locales, mode); + } + + /** + * Returns a list of matching {@code Locale} instances using the filtering + * mechanism defined in RFC 4647. This is equivalent to + * {@link #filter(List, Collection, FilteringMode)} when {@code mode} is + * {@link FilteringMode#AUTOSELECT_FILTERING}. + * + * @param priorityList user's Language Priority List in which each language + * tag is sorted in descending order based on priority or weight + * @param locales {@code Locale} instances used for matching + * @return a list of {@code Locale} instances for matching language tags + * sorted in descending order based on priority or weight, or an empty + * list if nothing matches. The list is modifiable. + * @throws NullPointerException if {@code priorityList} or {@code locales} + * is {@code null} + * + * @since 1.8 + */ + public static List<Locale> filter(List<LanguageRange> priorityList, + Collection<Locale> locales) { + return filter(priorityList, locales, FilteringMode.AUTOSELECT_FILTERING); + } + + /** + * Returns a list of matching languages tags using the basic filtering + * mechanism defined in RFC 4647. + * + * @param priorityList user's Language Priority List in which each language + * tag is sorted in descending order based on priority or weight + * @param tags language tags + * @param mode filtering mode + * @return a list of matching language tags sorted in descending order + * based on priority or weight, or an empty list if nothing matches. + * The list is modifiable. + * @throws NullPointerException if {@code priorityList} or {@code tags} is + * {@code null} + * @throws IllegalArgumentException if one or more extended language ranges + * are included in the given list when + * {@link FilteringMode#REJECT_EXTENDED_RANGES} is specified + * + * @since 1.8 + */ + public static List<String> filterTags(List<LanguageRange> priorityList, + Collection<String> tags, + FilteringMode mode) { + return LocaleMatcher.filterTags(priorityList, tags, mode); + } + + /** + * Returns a list of matching languages tags using the basic filtering + * mechanism defined in RFC 4647. This is equivalent to + * {@link #filterTags(List, Collection, FilteringMode)} when {@code mode} + * is {@link FilteringMode#AUTOSELECT_FILTERING}. + * + * @param priorityList user's Language Priority List in which each language + * tag is sorted in descending order based on priority or weight + * @param tags language tags + * @return a list of matching language tags sorted in descending order + * based on priority or weight, or an empty list if nothing matches. + * The list is modifiable. + * @throws NullPointerException if {@code priorityList} or {@code tags} is + * {@code null} + * + * @since 1.8 + */ + public static List<String> filterTags(List<LanguageRange> priorityList, + Collection<String> tags) { + return filterTags(priorityList, tags, FilteringMode.AUTOSELECT_FILTERING); + } + + /** + * Returns a {@code Locale} instance for the best-matching language + * tag using the lookup mechanism defined in RFC 4647. + * + * @param priorityList user's Language Priority List in which each language + * tag is sorted in descending order based on priority or weight + * @param locales {@code Locale} instances used for matching + * @return the best matching <code>Locale</code> instance chosen based on + * priority or weight, or {@code null} if nothing matches. + * @throws NullPointerException if {@code priorityList} or {@code tags} is + * {@code null} + * + * @since 1.8 + */ + public static Locale lookup(List<LanguageRange> priorityList, + Collection<Locale> locales) { + return LocaleMatcher.lookup(priorityList, locales); + } + + /** + * Returns the best-matching language tag using the lookup mechanism + * defined in RFC 4647. + * + * @param priorityList user's Language Priority List in which each language + * tag is sorted in descending order based on priority or weight + * @param tags language tangs used for matching + * @return the best matching language tag chosen based on priority or + * weight, or {@code null} if nothing matches. + * @throws NullPointerException if {@code priorityList} or {@code tags} is + * {@code null} + * + * @since 1.8 + */ + public static String lookupTag(List<LanguageRange> priorityList, + Collection<String> tags) { + return LocaleMatcher.lookupTag(priorityList, tags); + } + }
--- a/src/share/classes/java/util/Properties.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/Properties.java Thu Oct 11 16:59:50 2012 -0700 @@ -34,7 +34,10 @@ import java.io.Writer; import java.io.OutputStreamWriter; import java.io.BufferedWriter; -import java.lang.reflect.*; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import sun.util.spi.XmlPropertiesProvider; /** * The {@code Properties} class represents a persistent set of @@ -866,7 +869,7 @@ { if (in == null) throw new NullPointerException(); - XMLUtils.load(this, in); + XmlSupport.load(this, in); in.close(); } @@ -934,7 +937,7 @@ { if (os == null) throw new NullPointerException(); - XMLUtils.save(this, os, comment, encoding); + XmlSupport.save(this, os, comment, encoding); } /** @@ -1113,59 +1116,82 @@ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; + /** + * Supporting class for loading/storing properties in XML format. + * + * <p> The {@code load} and {@code store} methods defined here delegate to a + * system-wide {@code XmlPropertiesProvider}. On first invocation of either + * method then the system-wide provider is located as follows: </p> + * + * <ol> + * <li> If the system property {@code sun.util.spi.XmlPropertiesProvider} + * is defined then it is taken to be the full-qualified name of a concrete + * provider class. The class is loaded with the system class loader as the + * initiating loader. If it cannot be loaded or instantiated using a zero + * argument constructor then an unspecified error is thrown. </li> + * + * <li> If the system property is not defined then the service-provider + * loading facility defined by the {@link ServiceLoader} class is used to + * locate a provider with the system class loader as the initiating + * loader and {@code sun.util.spi.XmlPropertiesProvider} as the service + * type. If this process fails then an unspecified error is thrown. If + * there is more than one service provider installed then it is + * not specified as to which provider will be used. </li> + * + * <li> If the provider is not found by the above means then a system + * default provider will be instantiated and used. </li> + * </ol> + */ + private static class XmlSupport { - private static class XMLUtils { - private static Method load = null; - private static Method save = null; - static { + private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) { + String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider"); + if (cn == null) + return null; try { - // reference sun.util.xml.Utils reflectively - // to allow the Properties class be compiled in - // the absence of XML - Class<?> c = Class.forName("sun.util.xml.XMLUtils", true, null); - load = c.getMethod("load", Properties.class, InputStream.class); - save = c.getMethod("save", Properties.class, OutputStream.class, - String.class, String.class); - } catch (ClassNotFoundException cnf) { - throw new AssertionError(cnf); - } catch (NoSuchMethodException e) { - throw new AssertionError(e); + Class<?> c = Class.forName(cn, true, cl); + return (XmlPropertiesProvider)c.newInstance(); + } catch (ClassNotFoundException | + IllegalAccessException | + InstantiationException x) { + throw new ServiceConfigurationError(null, x); } } - static void invoke(Method m, Object... args) throws IOException { - try { - m.invoke(null, args); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - Throwable t = e.getCause(); - if (t instanceof RuntimeException) - throw (RuntimeException)t; + private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) { + Iterator<XmlPropertiesProvider> iterator = + ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator(); + return iterator.hasNext() ? iterator.next() : null; + } - if (t instanceof IOException) { - throw (IOException)t; - } else { - throw new AssertionError(t); - } - } + private static XmlPropertiesProvider loadProvider() { + return AccessController.doPrivileged( + new PrivilegedAction<XmlPropertiesProvider>() { + public XmlPropertiesProvider run() { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + XmlPropertiesProvider provider = loadProviderFromProperty(cl); + if (provider != null) + return provider; + provider = loadProviderAsService(cl); + if (provider != null) + return provider; + throw new InternalError("No fallback"); + }}); } + private static final XmlPropertiesProvider PROVIDER = loadProvider(); + static void load(Properties props, InputStream in) throws IOException, InvalidPropertiesFormatException { - if (load == null) - throw new InternalError("sun.util.xml.XMLUtils not found"); - invoke(load, props, in); + PROVIDER.load(props, in); } static void save(Properties props, OutputStream os, String comment, String encoding) throws IOException { - if (save == null) - throw new InternalError("sun.util.xml.XMLUtils not found"); - invoke(save, props, os, comment, encoding); + PROVIDER.store(props, os, comment, encoding); } } }
--- a/src/share/classes/java/util/PropertyPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/PropertyPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -130,18 +130,15 @@ * @param mask the actions mask to use. * */ - - private void init(int mask) - { - + private void init(int mask) { if ((mask & ALL) != mask) - throw new IllegalArgumentException("invalid actions mask"); + throw new IllegalArgumentException("invalid actions mask"); if (mask == NONE) - throw new IllegalArgumentException("invalid actions mask"); + throw new IllegalArgumentException("invalid actions mask"); if (getName() == null) - throw new NullPointerException("name can't be null"); + throw new NullPointerException("name can't be null"); this.mask = mask; } @@ -160,9 +157,7 @@ * @throws IllegalArgumentException if <code>name</code> is empty or if * <code>actions</code> is invalid. */ - - public PropertyPermission(String name, String actions) - { + public PropertyPermission(String name, String actions) { super(name,actions); init(getMask(actions)); } @@ -196,7 +191,6 @@ return ((this.mask & that.mask) == that.mask) && super.implies(that); } - /** * Checks two PropertyPermission objects for equality. Checks that <i>obj</i> is * a PropertyPermission, and has the same name and actions as this object. @@ -226,16 +220,14 @@ * * @return a hash code value for this object. */ - public int hashCode() { return this.getName().hashCode(); } - /** * Converts an actions String to an actions mask. * - * @param action the action string. + * @param actions the action string. * @return the actions mask. */ private static int getMask(String actions) { @@ -332,8 +324,7 @@ * * @return the canonical string representation of the actions. */ - static String getActions(int mask) - { + static String getActions(int mask) { StringBuilder sb = new StringBuilder(); boolean comma = false; @@ -359,8 +350,7 @@ * * @return the canonical string representation of the actions. */ - public String getActions() - { + public String getActions() { if (actions == null) actions = getActions(this.mask); @@ -373,7 +363,6 @@ * * @return the actions mask. */ - int getMask() { return mask; } @@ -386,7 +375,6 @@ * @return a new PermissionCollection object suitable for storing * PropertyPermissions. */ - public PermissionCollection newPermissionCollection() { return new PropertyPermissionCollection(); } @@ -436,7 +424,7 @@ * @serial include */ final class PropertyPermissionCollection extends PermissionCollection -implements Serializable + implements Serializable { /** @@ -454,10 +442,8 @@ private boolean all_allowed; /** - * Create an empty PropertyPermissions object. - * + * Create an empty PropertyPermissionCollection object. */ - public PropertyPermissionCollection() { perms = new HashMap<>(32); // Capacity for default policy all_allowed = false; @@ -475,9 +461,7 @@ * @exception SecurityException - if this PropertyPermissionCollection * object has been marked readonly */ - - public void add(Permission permission) - { + public void add(Permission permission) { if (! (permission instanceof PropertyPermission)) throw new IllegalArgumentException("invalid permission: "+ permission); @@ -514,14 +498,12 @@ * Check and see if this set of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if "permission" is a proper subset of a permission in * the set, false if not. */ - - public boolean implies(Permission permission) - { + public boolean implies(Permission permission) { if (! (permission instanceof PropertyPermission)) return false; @@ -655,8 +637,9 @@ * Reads in a Hashtable of PropertyPermissions and saves them in the * perms field. Reads in all_allowed. */ - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { // Don't call defaultReadObject() // Read in serialized fields
--- a/src/share/classes/java/util/RegularEnumSet.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/RegularEnumSet.java Thu Oct 11 16:59:50 2012 -0700 @@ -289,7 +289,7 @@ * the same size, and every member of the given set is contained in * this set. * - * @param e object to be compared for equality with this set + * @param o object to be compared for equality with this set * @return <tt>true</tt> if the specified object is equal to this set */ public boolean equals(Object o) {
--- a/src/share/classes/java/util/Scanner.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/Scanner.java Thu Oct 11 16:59:50 2012 -0700 @@ -568,9 +568,8 @@ * Constructs a <code>Scanner</code> that returns values scanned * from the specified source delimited by the specified pattern. * - * @param source A character source implementing the Readable interface + * @param source A character source implementing the Readable interface * @param pattern A delimiting pattern - * @return A scanner with the specified source and pattern */ private Scanner(Readable source, Pattern pattern) { assert source != null : "source should not be null";
--- a/src/share/classes/java/util/ServiceLoader.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/ServiceLoader.java Thu Oct 11 16:59:50 2012 -0700 @@ -213,7 +213,7 @@ } private ServiceLoader(Class<S> svc, ClassLoader cl) { - service = svc; + service = Objects.requireNonNull(svc, "Service interface cannot be null"); loader = cl; reload(); }
--- a/src/share/classes/java/util/TimeZone.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/TimeZone.java Thu Oct 11 16:59:50 2012 -0700 @@ -221,7 +221,7 @@ * @param date the milliseconds (since January 1, 1970, * 00:00:00.000 GMT) at which the time zone offset and daylight * saving amount are found - * @param offset an array of int where the raw GMT offset + * @param offsets an array of int where the raw GMT offset * (offset[0]) and daylight saving amount (offset[1]) are stored, * or null if those values are not needed. The method assumes that * the length of the given array is two or larger.
--- a/src/share/classes/java/util/logging/Logging.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/logging/Logging.java Thu Oct 11 16:59:50 2012 -0700 @@ -41,8 +41,8 @@ * @since 1.5 * * @see javax.management - * @see java.util.Logger - * @see java.util.LogManager + * @see Logger + * @see LogManager */ class Logging implements LoggingMXBean {
--- a/src/share/classes/java/util/prefs/XmlSupport.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/java/util/prefs/XmlSupport.java Thu Oct 11 16:59:50 2012 -0700 @@ -92,7 +92,7 @@ * @throws BackingStoreException if preference data cannot be read from * backing store. * @throws IllegalStateException if this node (or an ancestor) has been - * removed with the {@link #removeNode()} method. + * removed with the {@link Preferences#removeNode()} method. */ static void export(OutputStream os, final Preferences p, boolean subTree) throws IOException, BackingStoreException {
--- a/src/share/classes/javax/crypto/CryptoAllPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/crypto/CryptoAllPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -136,8 +136,7 @@ * @exception SecurityException - if this CryptoAllPermissionCollection * object has been marked readonly */ - public void add(Permission permission) - { + public void add(Permission permission) { if (isReadOnly()) throw new SecurityException("attempt to add a Permission to " + "a readonly PermissionCollection"); @@ -152,13 +151,12 @@ * Check and see if this set of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if the given permission is implied by this * CryptoAllPermissionCollection. */ - public boolean implies(Permission permission) - { + public boolean implies(Permission permission) { if (!(permission instanceof CryptoPermission)) { return false; }
--- a/src/share/classes/javax/crypto/CryptoPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/crypto/CryptoPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -471,8 +471,8 @@ * @author Sharon Liu */ final class CryptoPermissionCollection extends PermissionCollection -implements Serializable { - + implements Serializable +{ private static final long serialVersionUID = -511215555898802763L; private Vector<Permission> permissions; @@ -493,8 +493,7 @@ * @exception SecurityException - if this CryptoPermissionCollection * object has been marked <i>readOnly</i>. */ - public void add(Permission permission) - { + public void add(Permission permission) { if (isReadOnly()) throw new SecurityException("attempt to add a Permission " + "to a readonly PermissionCollection"); @@ -506,10 +505,10 @@ } /** - * Check and see if this CryptoPermission object implies - * the given Permission object. + * Check and see if this CryptoPermission object implies + * the given Permission object. * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if the given permission is implied by this * CryptoPermissionCollection, false if not. @@ -538,8 +537,7 @@ * @return an enumeration of all the CryptoPermission objects. */ - public Enumeration<Permission> elements() - { + public Enumeration<Permission> elements() { return permissions.elements(); } }
--- a/src/share/classes/javax/crypto/CryptoPolicyParser.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/crypto/CryptoPolicyParser.java Thu Oct 11 16:59:50 2012 -0700 @@ -54,7 +54,7 @@ * @author Sharon Liu * * @see java.security.Permissions - * @see java.security.spec.AlgrithomParameterSpec + * @see java.security.spec.AlgorithmParameterSpec * @see javax.crypto.CryptoPermission * @see javax.crypto.CryptoAllPermission * @see javax.crypto.CryptoPermissions
--- a/src/share/classes/javax/crypto/NullCipherSpi.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/crypto/NullCipherSpi.java Thu Oct 11 16:59:50 2012 -0700 @@ -33,7 +33,7 @@ * tranform the plaintext. * * @author Li Gong - * @see Nullcipher + * @see NullCipher * * @since 1.4 */
--- a/src/share/classes/javax/management/loading/MLet.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/management/loading/MLet.java Thu Oct 11 16:59:50 2012 -0700 @@ -798,7 +798,7 @@ * Allows the m-let to perform any operations it needs before being unregistered * by the MBean server. * - * @exception java.langException This exception should be caught + * @exception java.lang.Exception This exception should be caught * by the MBean server and re-thrown as an * MBeanRegistrationException. */
--- a/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Thu Oct 11 16:59:50 2012 -0700 @@ -189,7 +189,7 @@ * May be null if the property is write-only. * @param setter The method used for writing the attribute value. * May be null if the attribute is read-only. - * @exception IntrospectionException There is a consistency + * @exception javax.management.IntrospectionException There is a consistency * problem in the definition of this attribute. * */ @@ -233,7 +233,7 @@ * it is null, then a default descriptor will be created. If * the descriptor does not contain the field "displayName" this field is added * in the descriptor with its default value. - * @exception IntrospectionException There is a consistency + * @exception javax.management.IntrospectionException There is a consistency * problem in the definition of this attribute. * @exception RuntimeOperationsException Wraps an * IllegalArgumentException. The descriptor is invalid, or descriptor
--- a/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Thu Oct 11 16:59:50 2012 -0700 @@ -124,11 +124,6 @@ <p>Construct a handler backed by the given {@code CompositeData}.</p> - @param mbsc the {@code MBeanServerConnection} related to this - {@code CompositeData}. This is only relevant if a method in - the interface for which this is an invocation handler returns - a type that is an MXBean interface. Otherwise, it can be null. - @param compositeData the {@code CompositeData} that will supply information to getters.
--- a/src/share/classes/javax/naming/spi/NamingManager.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/naming/spi/NamingManager.java Thu Oct 11 16:59:50 2012 -0700 @@ -416,7 +416,7 @@ * specified. * See the <code>getObjectInstance</code> method for * details. - * @param ctx The context relative to which <code>name</code> is + * @param nameCtx The context relative to which <code>name</code> is * specified, or null for the default initial context. * See the <code>getObjectInstance</code> method for * details.
--- a/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -178,7 +178,6 @@ * * @return a hash code value for this object. */ - public int hashCode() { return getName().hashCode(); } @@ -278,12 +277,11 @@ * Check and see if this collection of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if "permission" is a proper subset of a permission in * the collection, false if not. */ - public boolean implies(Permission permission) { if (! (permission instanceof DelegationPermission)) return false; @@ -310,7 +308,6 @@ * @exception SecurityException - if this PermissionCollection object * has been marked readonly */ - public void add(Permission permission) { if (! (permission instanceof DelegationPermission)) throw new IllegalArgumentException("invalid permission: "+ @@ -329,7 +326,6 @@ * * @return an enumeration of all the DelegationPermission objects. */ - public Enumeration<Permission> elements() { // Convert Iterator into Enumeration synchronized (this) { @@ -376,8 +372,9 @@ * Reads in a Vector of DelegationPermissions and saves them in the perms field. */ @SuppressWarnings("unchecked") - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { // Don't call defaultReadObject() // Read in serialized fields
--- a/src/share/classes/javax/security/auth/kerberos/ServicePermission.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/security/auth/kerberos/ServicePermission.java Thu Oct 11 16:59:50 2012 -0700 @@ -259,7 +259,6 @@ * Always returns present actions in the following order: * initiate, accept. */ - public String getActions() { if (actions == null) actions = getActions(this.mask); @@ -280,7 +279,6 @@ * @return a new PermissionCollection object suitable for storing * ServicePermissions. */ - public PermissionCollection newPermissionCollection() { return new KrbServicePermissionCollection(); } @@ -290,7 +288,6 @@ * * @return the actions mask. */ - int getMask() { return mask; } @@ -301,7 +298,6 @@ * @param action the action string * @return the action mask */ - private static int getMask(String action) { if (action == null) { @@ -468,12 +464,11 @@ * Check and see if this collection of permissions implies the permissions * expressed in "permission". * - * @param p the Permission object to compare + * @param permission the Permission object to compare * * @return true if "permission" is a proper subset of a permission in * the collection, false if not. */ - public boolean implies(Permission permission) { if (! (permission instanceof ServicePermission)) return false; @@ -517,7 +512,6 @@ * @exception SecurityException - if this PermissionCollection object * has been marked readonly */ - public void add(Permission permission) { if (! (permission instanceof ServicePermission)) throw new IllegalArgumentException("invalid permission: "+ @@ -584,8 +578,9 @@ * Reads in a Vector of ServicePermissions and saves them in the perms field. */ @SuppressWarnings("unchecked") - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { // Don't call defaultReadObject() // Read in serialized fields
--- a/src/share/classes/javax/sql/ConnectionPoolDataSource.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/sql/ConnectionPoolDataSource.java Thu Oct 11 16:59:50 2012 -0700 @@ -48,7 +48,7 @@ * connection to the database that this * <code>ConnectionPoolDataSource</code> object represents * @exception SQLException if a database access error occurs - * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.4 */ @@ -64,7 +64,7 @@ * connection to the database that this * <code>ConnectionPoolDataSource</code> object represents * @exception SQLException if a database access error occurs - * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.4 */
--- a/src/share/classes/javax/sql/PooledConnection.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/sql/PooledConnection.java Thu Oct 11 16:59:50 2012 -0700 @@ -102,7 +102,7 @@ * @return a <code>Connection</code> object that is a handle to * this <code>PooledConnection</code> object * @exception SQLException if a database access error occurs - * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.4 */ @@ -117,7 +117,7 @@ * information. * * @exception SQLException if a database access error occurs - * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * @exception java.sql.SQLFeatureNotSupportedException if the JDBC driver does not support * this method * @since 1.4 */
--- a/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Thu Oct 11 16:59:50 2012 -0700 @@ -293,7 +293,7 @@ * SyncProvider.DATASOURCE_TABLE_LOCK, * SyncProvider.DATASOURCE_DB_LOCK * </pre> - * @throws SyncProviderExceptiom if an error occurs determining the data + * @throws SyncProviderException if an error occurs determining the data * source locking level. * @see #setDataSourceLock
--- a/src/share/classes/javax/swing/ToolTipManager.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/swing/ToolTipManager.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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 @@ -217,6 +217,25 @@ return exitTimer.getInitialDelay(); } + // Returns GraphicsConfiguration instance that toFind belongs to or null + // if drawing point is set to a point beyond visible screen area (e.g. + // Point(20000, 20000)) + private GraphicsConfiguration getDrawingGC(Point toFind) { + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice devices[] = env.getScreenDevices(); + for (GraphicsDevice device : devices) { + GraphicsConfiguration configs[] = device.getConfigurations(); + for (GraphicsConfiguration config : configs) { + Rectangle rect = config.getBounds(); + if (rect.contains(toFind)) { + return config; + } + } + } + + return null; + } + void showTipWindow() { if(insideComponent == null || !insideComponent.isShowing()) return; @@ -231,9 +250,25 @@ if (enabled) { Dimension size; Point screenLocation = insideComponent.getLocationOnScreen(); - Point location = new Point(); - GraphicsConfiguration gc; - gc = insideComponent.getGraphicsConfiguration(); + Point location; + + Point toFind; + if (preferredLocation != null) { + toFind = new Point(screenLocation.x + preferredLocation.x, + screenLocation.y + preferredLocation.y); + } else { + toFind = mouseEvent.getLocationOnScreen(); + } + + GraphicsConfiguration gc = getDrawingGC(toFind); + if (gc == null) { + toFind = mouseEvent.getLocationOnScreen(); + gc = getDrawingGC(toFind); + if (gc == null) { + gc = insideComponent.getGraphicsConfiguration(); + } + } + Rectangle sBounds = gc.getBounds(); Insets screenInsets = Toolkit.getDefaultToolkit() .getScreenInsets(gc); @@ -253,14 +288,13 @@ size = tip.getPreferredSize(); if(preferredLocation != null) { - location.x = screenLocation.x + preferredLocation.x; - location.y = screenLocation.y + preferredLocation.y; + location = toFind; if (!leftToRight) { location.x -= size.width; } } else { - location.x = screenLocation.x + mouseEvent.getX(); - location.y = screenLocation.y + mouseEvent.getY() + 20; + location = new Point(screenLocation.x + mouseEvent.getX(), + screenLocation.y + mouseEvent.getY() + 20); if (!leftToRight) { if(location.x - size.width>=0) { location.x -= size.width;
--- a/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java Thu Oct 11 16:59:50 2012 -0700 @@ -57,6 +57,8 @@ RecentSwatchPanel recentSwatchPanel; MouseListener mainSwatchListener; MouseListener recentSwatchListener; + private KeyListener mainSwatchKeyListener; + private KeyListener recentSwatchKeyListener; public DefaultSwatchChooserPanel() { super(); @@ -151,10 +153,14 @@ recentSwatchPanel.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, recentStr); + mainSwatchKeyListener = new MainSwatchKeyListener(); mainSwatchListener = new MainSwatchListener(); swatchPanel.addMouseListener(mainSwatchListener); + swatchPanel.addKeyListener(mainSwatchKeyListener); recentSwatchListener = new RecentSwatchListener(); + recentSwatchKeyListener = new RecentSwatchKeyListener(); recentSwatchPanel.addMouseListener(recentSwatchListener); + recentSwatchPanel.addKeyListener(recentSwatchKeyListener); JPanel mainHolder = new JPanel(new BorderLayout()); Border border = new CompoundBorder( new LineBorder(Color.black), @@ -196,11 +202,17 @@ public void uninstallChooserPanel(JColorChooser enclosingChooser) { super.uninstallChooserPanel(enclosingChooser); swatchPanel.removeMouseListener(mainSwatchListener); + swatchPanel.removeKeyListener(mainSwatchKeyListener); recentSwatchPanel.removeMouseListener(recentSwatchListener); + recentSwatchPanel.removeKeyListener(recentSwatchKeyListener); + swatchPanel = null; recentSwatchPanel = null; mainSwatchListener = null; + mainSwatchKeyListener = null; recentSwatchListener = null; + recentSwatchKeyListener = null; + removeAll(); // strip out all the sub-components } @@ -209,11 +221,32 @@ } + private class RecentSwatchKeyListener extends KeyAdapter { + public void keyPressed(KeyEvent e) { + if (KeyEvent.VK_SPACE == e.getKeyCode()) { + Color color = recentSwatchPanel.getSelectedColor(); + setSelectedColor(color); + } + } + } + + private class MainSwatchKeyListener extends KeyAdapter { + public void keyPressed(KeyEvent e) { + if (KeyEvent.VK_SPACE == e.getKeyCode()) { + Color color = swatchPanel.getSelectedColor(); + setSelectedColor(color); + recentSwatchPanel.setMostRecentColor(color); + } + } + } + class RecentSwatchListener extends MouseAdapter implements Serializable { public void mousePressed(MouseEvent e) { if (isEnabled()) { Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY()); + recentSwatchPanel.setSelectedColorFromLocation(e.getX(), e.getY()); setSelectedColor(color); + recentSwatchPanel.requestFocusInWindow(); } } } @@ -223,7 +256,9 @@ if (isEnabled()) { Color color = swatchPanel.getColorForLocation(e.getX(), e.getY()); setSelectedColor(color); + swatchPanel.setSelectedColorFromLocation(e.getX(), e.getY()); recentSwatchPanel.setMostRecentColor(color); + swatchPanel.requestFocusInWindow(); } } } @@ -239,18 +274,81 @@ protected Dimension numSwatches; protected Dimension gap; + private int selRow; + private int selCol; + public SwatchPanel() { initValues(); initColors(); setToolTipText(""); // register for events setOpaque(true); setBackground(Color.white); - setRequestFocusEnabled(false); + setFocusable(true); setInheritsPopupMenu(true); + + addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + repaint(); + } + + public void focusLost(FocusEvent e) { + repaint(); + } + }); + + addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + int typed = e.getKeyCode(); + switch (typed) { + case KeyEvent.VK_UP: + if (selRow > 0) { + selRow--; + repaint(); + } + break; + case KeyEvent.VK_DOWN: + if (selRow < numSwatches.height - 1) { + selRow++; + repaint(); + } + break; + case KeyEvent.VK_LEFT: + if (selCol > 0 && SwatchPanel.this.getComponentOrientation().isLeftToRight()) { + selCol--; + repaint(); + } else if (selCol < numSwatches.width - 1 + && !SwatchPanel.this.getComponentOrientation().isLeftToRight()) { + selCol++; + repaint(); + } + break; + case KeyEvent.VK_RIGHT: + if (selCol < numSwatches.width - 1 + && SwatchPanel.this.getComponentOrientation().isLeftToRight()) { + selCol++; + repaint(); + } else if (selCol > 0 && !SwatchPanel.this.getComponentOrientation().isLeftToRight()) { + selCol--; + repaint(); + } + break; + case KeyEvent.VK_HOME: + selCol = 0; + selRow = 0; + repaint(); + break; + case KeyEvent.VK_END: + selCol = numSwatches.width - 1; + selRow = numSwatches.height - 1; + repaint(); + break; + } + } + }); } - public boolean isFocusTraversable() { - return false; + public Color getSelectedColor() { + return getColorForCell(selCol, selRow); } protected void initValues() { @@ -263,11 +361,10 @@ for (int row = 0; row < numSwatches.height; row++) { int y = row * (swatchSize.height + gap.height); for (int column = 0; column < numSwatches.width; column++) { - - g.setColor( getColorForCell(column, row) ); + Color c = getColorForCell(column, row); + g.setColor(c); int x; - if ((!this.getComponentOrientation().isLeftToRight()) && - (this instanceof RecentSwatchPanel)) { + if (!this.getComponentOrientation().isLeftToRight()) { x = (numSwatches.width - column - 1) * (swatchSize.width + gap.width); } else { x = column * (swatchSize.width + gap.width); @@ -276,6 +373,20 @@ g.setColor(Color.black); g.drawLine( x+swatchSize.width-1, y, x+swatchSize.width-1, y+swatchSize.height-1); g.drawLine( x, y+swatchSize.height-1, x+swatchSize.width-1, y+swatchSize.height-1); + + if (selRow == row && selCol == column && this.isFocusOwner()) { + Color c2 = new Color(c.getRed() < 125 ? 255 : 0, + c.getGreen() < 125 ? 255 : 0, + c.getBlue() < 125 ? 255 : 0); + g.setColor(c2); + + g.drawLine(x, y, x + swatchSize.width - 1, y); + g.drawLine(x, y, x, y + swatchSize.height - 1); + g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1, y + swatchSize.height - 1); + g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y + swatchSize.height - 1); + g.drawLine(x, y, x + swatchSize.width - 1, y + swatchSize.height - 1); + g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y); + } } } } @@ -296,10 +407,19 @@ return color.getRed()+", "+ color.getGreen() + ", " + color.getBlue(); } + public void setSelectedColorFromLocation(int x, int y) { + if (!this.getComponentOrientation().isLeftToRight()) { + selCol = numSwatches.width - x / (swatchSize.width + gap.width) - 1; + } else { + selCol = x / (swatchSize.width + gap.width); + } + selRow = y / (swatchSize.height + gap.height); + repaint(); + } + public Color getColorForLocation( int x, int y ) { int column; - if ((!this.getComponentOrientation().isLeftToRight()) && - (this instanceof RecentSwatchPanel)) { + if (!this.getComponentOrientation().isLeftToRight()) { column = numSwatches.width - x / (swatchSize.width + gap.width) - 1; } else { column = x / (swatchSize.width + gap.width);
--- a/src/share/classes/sun/net/www/http/HttpClient.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/net/www/http/HttpClient.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2012, 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 @@ -36,6 +36,7 @@ import sun.net.www.ParseUtil; import sun.net.www.protocol.http.HttpURLConnection; import sun.util.logging.PlatformLogger; +import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; /** * @author Herb Jellinek @@ -244,16 +245,17 @@ */ public static HttpClient New(URL url) throws IOException { - return HttpClient.New(url, Proxy.NO_PROXY, -1, true); + return HttpClient.New(url, Proxy.NO_PROXY, -1, true, null); } public static HttpClient New(URL url, boolean useCache) throws IOException { - return HttpClient.New(url, Proxy.NO_PROXY, -1, useCache); + return HttpClient.New(url, Proxy.NO_PROXY, -1, useCache, null); } - public static HttpClient New(URL url, Proxy p, int to, boolean useCache) - throws IOException { + public static HttpClient New(URL url, Proxy p, int to, boolean useCache, + HttpURLConnection httpuc) throws IOException + { if (p == null) { p = Proxy.NO_PROXY; } @@ -261,6 +263,13 @@ /* see if one's already around */ if (useCache) { ret = kac.get(url, null); + if (ret != null && httpuc != null && + httpuc.streaming() && + httpuc.getRequestMethod() == "POST") { + if (!ret.available()) + ret = null; + } + if (ret != null) { if ((ret.proxy != null && ret.proxy.equals(p)) || (ret.proxy == null && p == null)) { @@ -268,6 +277,8 @@ ret.cachedHttpClient = true; assert ret.inCache; ret.inCache = false; + if (httpuc != null && ret.needsTunneling()) + httpuc.setTunnelState(TUNNELING); PlatformLogger logger = HttpURLConnection.getHttpLogger(); if (logger.isLoggable(PlatformLogger.FINEST)) { logger.finest("KeepAlive stream retrieved from the cache, " + ret); @@ -302,20 +313,25 @@ return ret; } - public static HttpClient New(URL url, Proxy p, int to) throws IOException { - return New(url, p, to, true); + public static HttpClient New(URL url, Proxy p, int to, + HttpURLConnection httpuc) throws IOException + { + return New(url, p, to, true, httpuc); } public static HttpClient New(URL url, String proxyHost, int proxyPort, boolean useCache) throws IOException { - return New(url, newHttpProxy(proxyHost, proxyPort, "http"), -1, useCache); + return New(url, newHttpProxy(proxyHost, proxyPort, "http"), + -1, useCache, null); } public static HttpClient New(URL url, String proxyHost, int proxyPort, - boolean useCache, int to) + boolean useCache, int to, + HttpURLConnection httpuc) throws IOException { - return New(url, newHttpProxy(proxyHost, proxyPort, "http"), to, useCache); + return New(url, newHttpProxy(proxyHost, proxyPort, "http"), + to, useCache, httpuc); } /* return it to the cache as still usable, if: @@ -344,6 +360,34 @@ } } + protected synchronized boolean available() throws IOException { + boolean available = true; + int old = serverSocket.getSoTimeout(); + serverSocket.setSoTimeout(1); + BufferedInputStream tmpbuf = + new BufferedInputStream(serverSocket.getInputStream()); + + PlatformLogger logger = HttpURLConnection.getHttpLogger(); + try { + int r = tmpbuf.read(); + if (r == -1) { + if (logger.isLoggable(PlatformLogger.FINEST)) { + logger.finest("HttpClient.available(): " + + "read returned -1: not available"); + } + available = false; + } + } catch (SocketTimeoutException e) { + if (logger.isLoggable(PlatformLogger.FINEST)) { + logger.finest("HttpClient.available(): " + + "SocketTimeout: its available"); + } + } finally { + serverSocket.setSoTimeout(old); + } + return available; + } + protected synchronized void putInKeepAliveCache() { if (inCache) { assert false : "Duplicate put to keep alive cache";
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2012, 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 @@ -351,7 +351,7 @@ private HttpClient reuseClient = null; /* Tunnel states */ - enum TunnelState { + public enum TunnelState { /* No tunnel */ NONE, @@ -662,7 +662,7 @@ */ protected void setNewClient (URL url, boolean useCache) throws IOException { - http = HttpClient.New(url, null, -1, useCache, connectTimeout); + http = HttpClient.New(url, null, -1, useCache, connectTimeout, this); http.setReadTimeout(readTimeout); } @@ -703,7 +703,8 @@ String proxyHost, int proxyPort, boolean useCache) throws IOException { - http = HttpClient.New (url, proxyHost, proxyPort, useCache, connectTimeout); + http = HttpClient.New (url, proxyHost, proxyPort, useCache, + connectTimeout, this); http.setReadTimeout(readTimeout); } @@ -994,14 +995,14 @@ // subclass HttpsClient will overwrite & return an instance of HttpsClient protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout) throws IOException { - return HttpClient.New(url, p, connectTimeout); + return HttpClient.New(url, p, connectTimeout, this); } // subclass HttpsClient will overwrite & return an instance of HttpsClient protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout, boolean useCache) throws IOException { - return HttpClient.New(url, p, connectTimeout, useCache); + return HttpClient.New(url, p, connectTimeout, useCache, this); } private void expect100Continue() throws IOException { @@ -1144,7 +1145,7 @@ } } - private boolean streaming () { + public boolean streaming () { return (fixedContentLength != -1) || (fixedContentLengthLong != -1) || (chunkLength != -1); } @@ -1739,7 +1740,7 @@ * * @param the state */ - void setTunnelState(TunnelState tunnelState) { + public void setTunnelState(TunnelState tunnelState) { this.tunnelState = tunnelState; }
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -1059,6 +1059,28 @@ return translateReadyOps(ops, 0, sk); } + // package-private + int poll(int events, long timeout) throws IOException { + assert Thread.holdsLock(blockingLock()) && !isBlocking(); + + synchronized (readLock) { + int n = 0; + try { + begin(); + synchronized (stateLock) { + if (!isOpen()) + return 0; + readerThread = NativeThread.current(); + } + n = Net.poll(fd, events, timeout); + } finally { + readerThread = 0; + end(n > 0); + } + return n; + } + } + /** * Translates an interest operation set into a native poll event set */
--- a/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java Thu Oct 11 16:59:50 2012 -0700 @@ -176,40 +176,31 @@ return dc.receive(bb); } - // Implement timeout with a selector - SelectionKey sk = null; - Selector sel = null; dc.configureBlocking(false); try { int n; SocketAddress sender; if ((sender = dc.receive(bb)) != null) return sender; - sel = Util.getTemporarySelector(dc); - sk = dc.register(sel, SelectionKey.OP_READ); long to = timeout; for (;;) { if (!dc.isOpen()) throw new ClosedChannelException(); long st = System.currentTimeMillis(); - int ns = sel.select(to); - if (ns > 0 && sk.isReadable()) { + int result = dc.poll(PollArrayWrapper.POLLIN, to); + if (result > 0 && + ((result & PollArrayWrapper.POLLIN) != 0)) { if ((sender = dc.receive(bb)) != null) return sender; } - sel.selectedKeys().remove(sk); to -= System.currentTimeMillis() - st; if (to <= 0) throw new SocketTimeoutException(); } } finally { - if (sk != null) - sk.cancel(); if (dc.isOpen()) dc.configureBlocking(true); - if (sel != null) - Util.releaseTemporarySelector(sel); } }
--- a/src/share/classes/sun/nio/ch/Net.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/Net.java Thu Oct 11 16:59:50 2012 -0700 @@ -409,6 +409,9 @@ int level, int opt, int arg) throws IOException; + static native int poll(FileDescriptor fd, int events, long timeout) + throws IOException; + // -- Multicast support --
--- a/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Oct 11 16:59:50 2012 -0700 @@ -102,37 +102,26 @@ return sc.socket(); } - // Implement timeout with a selector - SelectionKey sk = null; - Selector sel = null; ssc.configureBlocking(false); try { SocketChannel sc; if ((sc = ssc.accept()) != null) return sc.socket(); - sel = Util.getTemporarySelector(ssc); - sk = ssc.register(sel, SelectionKey.OP_ACCEPT); long to = timeout; for (;;) { if (!ssc.isOpen()) throw new ClosedChannelException(); long st = System.currentTimeMillis(); - int ns = sel.select(to); - if (ns > 0 && - sk.isAcceptable() && ((sc = ssc.accept()) != null)) + int result = ssc.poll(PollArrayWrapper.POLLIN, to); + if (result > 0 && ((sc = ssc.accept()) != null)) return sc.socket(); - sel.selectedKeys().remove(sk); to -= System.currentTimeMillis() - st; if (to <= 0) throw new SocketTimeoutException(); } } finally { - if (sk != null) - sk.cancel(); if (ssc.isOpen()) ssc.configureBlocking(true); - if (sel != null) - Util.releaseTemporarySelector(sel); } } catch (Exception x) {
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -324,6 +324,28 @@ return translateReadyOps(ops, 0, sk); } + // package-private + int poll(int events, long timeout) throws IOException { + assert Thread.holdsLock(blockingLock()) && !isBlocking(); + + synchronized (lock) { + int n = 0; + try { + begin(); + synchronized (stateLock) { + if (!isOpen()) + return 0; + thread = NativeThread.current(); + } + n = Net.poll(fd, events, timeout); + } finally { + thread = 0; + end(n > 0); + } + return n; + } + } + /** * Translates an interest operation set into a native poll event set */
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Oct 11 16:59:50 2012 -0700 @@ -97,25 +97,19 @@ return; } - // Implement timeout with a selector - SelectionKey sk = null; - Selector sel = null; sc.configureBlocking(false); try { if (sc.connect(remote)) return; - sel = Util.getTemporarySelector(sc); - sk = sc.register(sel, SelectionKey.OP_CONNECT); long to = timeout; for (;;) { if (!sc.isOpen()) throw new ClosedChannelException(); long st = System.currentTimeMillis(); - int ns = sel.select(to); - if (ns > 0 && - sk.isConnectable() && sc.finishConnect()) + + int result = sc.poll(PollArrayWrapper.POLLCONN, to); + if (result > 0 && sc.finishConnect()) break; - sel.selectedKeys().remove(sk); to -= System.currentTimeMillis() - st; if (to <= 0) { try { @@ -125,12 +119,8 @@ } } } finally { - if (sk != null) - sk.cancel(); if (sc.isOpen()) sc.configureBlocking(true); - if (sel != null) - Util.releaseTemporarySelector(sel); } } catch (Exception x) { @@ -199,39 +189,29 @@ throw new IllegalBlockingModeException(); if (timeout == 0) return sc.read(bb); + sc.configureBlocking(false); - // Implement timeout with a selector - SelectionKey sk = null; - Selector sel = null; - sc.configureBlocking(false); try { int n; if ((n = sc.read(bb)) != 0) return n; - sel = Util.getTemporarySelector(sc); - sk = sc.register(sel, SelectionKey.OP_READ); long to = timeout; for (;;) { if (!sc.isOpen()) throw new ClosedChannelException(); long st = System.currentTimeMillis(); - int ns = sel.select(to); - if (ns > 0 && sk.isReadable()) { + int result = sc.poll(PollArrayWrapper.POLLIN, to); + if (result > 0) { if ((n = sc.read(bb)) != 0) return n; } - sel.selectedKeys().remove(sk); to -= System.currentTimeMillis() - st; if (to <= 0) throw new SocketTimeoutException(); } } finally { - if (sk != null) - sk.cancel(); if (sc.isOpen()) sc.configureBlocking(true); - if (sel != null) - Util.releaseTemporarySelector(sel); } }
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -914,6 +914,28 @@ return translateReadyOps(ops, 0, sk); } + // package-private + int poll(int events, long timeout) throws IOException { + assert Thread.holdsLock(blockingLock()) && !isBlocking(); + + synchronized (readLock) { + int n = 0; + try { + begin(); + synchronized (stateLock) { + if (!isOpen()) + return 0; + readerThread = NativeThread.current(); + } + n = Net.poll(fd, events, timeout); + } finally { + readerCleanup(); + end(n > 0); + } + return n; + } + } + /** * Translates an interest operation set into a native poll event set */
--- a/src/share/classes/sun/nio/ch/Util.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/nio/ch/Util.java Thu Oct 11 16:59:50 2012 -0700 @@ -218,66 +218,6 @@ ((DirectBuffer)buf).cleaner().clean(); } - private static class SelectorWrapper { - private Selector sel; - private SelectorWrapper (Selector sel) { - this.sel = sel; - Cleaner.create(this, new Closer(sel)); - } - private static class Closer implements Runnable { - private Selector sel; - private Closer (Selector sel) { - this.sel = sel; - } - public void run () { - try { - sel.close(); - } catch (Throwable th) { - throw new Error(th); - } - } - } - public Selector get() { return sel;} - } - - // Per-thread cached selector - private static ThreadLocal<SoftReference<SelectorWrapper>> localSelector - = new ThreadLocal<SoftReference<SelectorWrapper>>(); - // Hold a reference to the selWrapper object to prevent it from - // being cleaned when the temporary selector wrapped is on lease. - private static ThreadLocal<SelectorWrapper> localSelectorWrapper - = new ThreadLocal<SelectorWrapper>(); - - // When finished, invoker must ensure that selector is empty - // by cancelling any related keys and explicitly releasing - // the selector by invoking releaseTemporarySelector() - static Selector getTemporarySelector(SelectableChannel sc) - throws IOException - { - SoftReference<SelectorWrapper> ref = localSelector.get(); - SelectorWrapper selWrapper = null; - Selector sel = null; - if (ref == null - || ((selWrapper = ref.get()) == null) - || ((sel = selWrapper.get()) == null) - || (sel.provider() != sc.provider())) { - sel = sc.provider().openSelector(); - selWrapper = new SelectorWrapper(sel); - localSelector.set(new SoftReference<SelectorWrapper>(selWrapper)); - } - localSelectorWrapper.set(selWrapper); - return sel; - } - - static void releaseTemporarySelector(Selector sel) - throws IOException - { - // Selector should be empty - sel.selectNow(); // Flush cancelled keys - assert sel.keys().isEmpty() : "Temporary selector not empty"; - localSelectorWrapper.set(null); - } - // -- Random stuff --
--- a/src/share/classes/sun/security/pkcs11/P11Cipher.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/pkcs11/P11Cipher.java Thu Oct 11 16:59:50 2012 -0700 @@ -193,9 +193,9 @@ } else { // DES, DESede, Blowfish blockSize = 8; } - this.blockMode = - (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB); } + this.blockMode = + (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB); String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding"); String paddingStr = (algoParts.length > 2 ? algoParts[2] : defPadding);
--- a/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/provider/DSAKeyPairGenerator.java Thu Oct 11 16:59:50 2012 -0700 @@ -82,7 +82,9 @@ } public void initialize(int modlen, SecureRandom random) { - initialize(modlen, false, random); + // generate new parameters when no precomputed ones available. + initialize(modlen, true, random); + this.forceNewParameters = false; } /**
--- a/src/share/classes/sun/security/provider/DSAParameterGenerator.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/provider/DSAParameterGenerator.java Thu Oct 11 16:59:50 2012 -0700 @@ -116,12 +116,13 @@ throw new InvalidAlgorithmParameterException("Invalid parameter"); } DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec) genParamSpec; - if (dsaGenParams.getPrimePLength() > 2048) { + int primePLen = dsaGenParams.getPrimePLength(); + if (primePLen > 2048) { throw new InvalidParameterException - ("Prime size should be 512 - 1024, or 2048"); + ("No support for prime size " + primePLen); } // directly initialize using the already validated values - this.valueL = dsaGenParams.getPrimePLength(); + this.valueL = primePLen; this.valueN = dsaGenParams.getSubprimeQLength(); this.seedLen = dsaGenParams.getSeedLength(); this.random = random;
--- a/src/share/classes/sun/security/provider/ParameterCache.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/provider/ParameterCache.java Thu Oct 11 16:59:50 2012 -0700 @@ -146,9 +146,14 @@ InvalidAlgorithmParameterException { AlgorithmParameterGenerator gen = AlgorithmParameterGenerator.getInstance("DSA"); - DSAGenParameterSpec genParams = - new DSAGenParameterSpec(primeLen, subprimeLen); - gen.init(genParams, random); + // Use init(int size, SecureRandom random) for legacy DSA key sizes + if (primeLen < 1024) { + gen.init(primeLen, random); + } else { + DSAGenParameterSpec genParams = + new DSAGenParameterSpec(primeLen, subprimeLen); + gen.init(genParams, random); + } AlgorithmParameters params = gen.generateParameters(); DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class); return spec; @@ -159,8 +164,9 @@ dsaCache = new ConcurrentHashMap<Integer,DSAParameterSpec>(); /* - * We support precomputed parameter for 512, 768 and 1024 bit - * moduli. In this file we provide both the seed and counter + * We support precomputed parameter for legacy 512, 768 bit moduli, + * and (L, N) combinations of (1024, 160), (2048, 224), (2048, 256). + * In this file we provide both the seed and counter * value of the generation process for each of these seeds, * for validation purposes. We also include the test vectors * from the DSA specification, FIPS 186, and the FIPS 186
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -132,7 +132,7 @@ */ final void write(HandshakeOutStream s) throws IOException { int len = messageLength(); - if (len > (1 << 24)) { + if (len >= Record.OVERFLOW_OF_INT24) { throw new SSLException("Handshake message too big" + ", type = " + messageType() + ", len = " + len); }
--- a/src/share/classes/sun/security/ssl/HandshakeOutStream.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/ssl/HandshakeOutStream.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -153,10 +153,12 @@ */ void putInt8(int i) throws IOException { + checkOverflow(i, Record.OVERFLOW_OF_INT08); r.write(i); } void putInt16(int i) throws IOException { + checkOverflow(i, Record.OVERFLOW_OF_INT16); if (r.availableDataBytes() < 2) { flush(); } @@ -165,6 +167,7 @@ } void putInt24(int i) throws IOException { + checkOverflow(i, Record.OVERFLOW_OF_INT24); if (r.availableDataBytes() < 3) { flush(); } @@ -191,6 +194,8 @@ if (b == null) { putInt8(0); return; + } else { + checkOverflow(b.length, Record.OVERFLOW_OF_INT08); } putInt8(b.length); write(b, 0, b.length); @@ -200,6 +205,8 @@ if (b == null) { putInt16(0); return; + } else { + checkOverflow(b.length, Record.OVERFLOW_OF_INT16); } putInt16(b.length); write(b, 0, b.length); @@ -209,8 +216,19 @@ if (b == null) { putInt24(0); return; + } else { + checkOverflow(b.length, Record.OVERFLOW_OF_INT24); } putInt24(b.length); write(b, 0, b.length); } + + private void checkOverflow(int length, int overflow) { + if (length >= overflow) { + // internal_error alert will be triggered + throw new RuntimeException( + "Field length overflow, the field length (" + + length + ") should be less than " + overflow); + } + } }
--- a/src/share/classes/sun/security/ssl/Record.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/security/ssl/Record.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012, 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 @@ -110,4 +110,10 @@ + maxPadding // padding + trailerSize; // MAC + /* + * The overflow values of integers of 8, 16 and 24 bits. + */ + static final int OVERFLOW_OF_INT08 = (1 << 8); + static final int OVERFLOW_OF_INT16 = (1 << 16); + static final int OVERFLOW_OF_INT24 = (1 << 24); }
--- a/src/share/classes/sun/text/SupplementaryCharacterData.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/text/SupplementaryCharacterData.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -32,6 +32,11 @@ public final class SupplementaryCharacterData implements Cloneable { /** + * A token used as a character-category value to identify ignore characters + */ + private static final byte IGNORE = -1; + + /** * An array for supplementary characters and values. * Lower one byte is used to keep a byte-value. * Upper three bytes are used to keep the first supplementary character @@ -78,7 +83,8 @@ } else if (index > (end-1)) { i = k; } else { - return dataTable[k] & 0xFF; + int v = dataTable[k] & 0xFF; + return (v == 0xFF) ? IGNORE : v; } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/locale/LocaleEquivalentMaps.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2012, 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 sun.util.locale; + +import java.util.HashMap; +import java.util.Map; + +/** + * Locale equivalent map for BCP47 Locale matching + */ +final class LocaleEquivalentMaps { + + static final Map<String, String> singleEquivMap; + static final Map<String, String[]> multiEquivsMap; + static final Map<String, String> regionVariantEquivMap; + + static { + singleEquivMap = new HashMap<>(); + multiEquivsMap = new HashMap<>(); + regionVariantEquivMap = new HashMap<>(); + + // This is an auto-generated file and should not be manually edited. + // LSR Revision: 2012-09-04 + singleEquivMap.put("ami", "i-ami"); + singleEquivMap.put("art-lojban", "jbo"); + singleEquivMap.put("ase", "sgn-us"); + singleEquivMap.put("ayx", "nun"); + singleEquivMap.put("bfi", "sgn-gb"); + singleEquivMap.put("bjd", "drl"); + singleEquivMap.put("bnn", "i-bnn"); + singleEquivMap.put("bzs", "sgn-br"); + singleEquivMap.put("cjr", "mom"); + singleEquivMap.put("cka", "cmr"); + singleEquivMap.put("cmk", "xch"); + singleEquivMap.put("cmn-hans", "zh-cmn-hans"); + singleEquivMap.put("cmn-hant", "zh-cmn-hant"); + singleEquivMap.put("cmr", "cka"); + singleEquivMap.put("csn", "sgn-co"); + singleEquivMap.put("dev", "gav"); + singleEquivMap.put("drh", "khk"); + singleEquivMap.put("drl", "bjd"); + singleEquivMap.put("dse", "sgn-nl"); + singleEquivMap.put("dsl", "sgn-dk"); + singleEquivMap.put("fsl", "sgn-fr"); + singleEquivMap.put("gan", "zh-gan"); + singleEquivMap.put("gav", "dev"); + singleEquivMap.put("gsg", "sgn-de"); + singleEquivMap.put("gss", "sgn-gr"); + singleEquivMap.put("he", "iw"); + singleEquivMap.put("hle", "sca"); + singleEquivMap.put("hrr", "jal"); + singleEquivMap.put("hsn", "zh-xiang"); + singleEquivMap.put("i-ami", "ami"); + singleEquivMap.put("i-bnn", "bnn"); + singleEquivMap.put("i-klingon", "tlh"); + singleEquivMap.put("i-lux", "lb"); + singleEquivMap.put("i-navajo", "nv"); + singleEquivMap.put("i-pwn", "pwn"); + singleEquivMap.put("i-tao", "tao"); + singleEquivMap.put("i-tay", "tay"); + singleEquivMap.put("i-tsu", "tsu"); + singleEquivMap.put("ibi", "opa"); + singleEquivMap.put("id", "in"); + singleEquivMap.put("in", "id"); + singleEquivMap.put("ise", "sgn-it"); + singleEquivMap.put("isg", "sgn-ie"); + singleEquivMap.put("iw", "he"); + singleEquivMap.put("jal", "hrr"); + singleEquivMap.put("jbo", "art-lojban"); + singleEquivMap.put("ji", "yi"); + singleEquivMap.put("jsl", "sgn-jp"); + singleEquivMap.put("jv", "jw"); + singleEquivMap.put("jw", "jv"); + singleEquivMap.put("kgh", "kml"); + singleEquivMap.put("khk", "drh"); + singleEquivMap.put("kml", "kgh"); + singleEquivMap.put("lb", "i-lux"); + singleEquivMap.put("lcq", "ppr"); + singleEquivMap.put("lrr", "yma"); + singleEquivMap.put("mfs", "sgn-mx"); + singleEquivMap.put("mo", "ro"); + singleEquivMap.put("mom", "cjr"); + singleEquivMap.put("nan", "zh-min-nan"); + singleEquivMap.put("nb", "no-bok"); + singleEquivMap.put("ncs", "sgn-ni"); + singleEquivMap.put("nn", "no-nyn"); + singleEquivMap.put("no-bok", "nb"); + singleEquivMap.put("no-nyn", "nn"); + singleEquivMap.put("nsl", "sgn-no"); + singleEquivMap.put("nun", "ayx"); + singleEquivMap.put("nv", "i-navajo"); + singleEquivMap.put("opa", "ibi"); + singleEquivMap.put("ppr", "lcq"); + singleEquivMap.put("psr", "sgn-pt"); + singleEquivMap.put("pwn", "i-pwn"); + singleEquivMap.put("ras", "tie"); + singleEquivMap.put("ro", "mo"); + singleEquivMap.put("sca", "hle"); + singleEquivMap.put("sfb", "sgn-be-fr"); + singleEquivMap.put("sfs", "sgn-za"); + singleEquivMap.put("sgg", "sgn-ch-de"); + singleEquivMap.put("sgn-be-fr", "sfb"); + singleEquivMap.put("sgn-be-nl", "vgt"); + singleEquivMap.put("sgn-br", "bzs"); + singleEquivMap.put("sgn-ch-de", "sgg"); + singleEquivMap.put("sgn-co", "csn"); + singleEquivMap.put("sgn-de", "gsg"); + singleEquivMap.put("sgn-dk", "dsl"); + singleEquivMap.put("sgn-es", "ssp"); + singleEquivMap.put("sgn-fr", "fsl"); + singleEquivMap.put("sgn-gb", "bfi"); + singleEquivMap.put("sgn-gr", "gss"); + singleEquivMap.put("sgn-ie", "isg"); + singleEquivMap.put("sgn-it", "ise"); + singleEquivMap.put("sgn-jp", "jsl"); + singleEquivMap.put("sgn-mx", "mfs"); + singleEquivMap.put("sgn-ni", "ncs"); + singleEquivMap.put("sgn-nl", "dse"); + singleEquivMap.put("sgn-no", "nsl"); + singleEquivMap.put("sgn-pt", "psr"); + singleEquivMap.put("sgn-se", "swl"); + singleEquivMap.put("sgn-us", "ase"); + singleEquivMap.put("sgn-za", "sfs"); + singleEquivMap.put("ssp", "sgn-es"); + singleEquivMap.put("swl", "sgn-se"); + singleEquivMap.put("tao", "i-tao"); + singleEquivMap.put("tay", "i-tay"); + singleEquivMap.put("tie", "ras"); + singleEquivMap.put("tkk", "twm"); + singleEquivMap.put("tlh", "i-klingon"); + singleEquivMap.put("tlw", "weo"); + singleEquivMap.put("tsu", "i-tsu"); + singleEquivMap.put("twm", "tkk"); + singleEquivMap.put("vgt", "sgn-be-nl"); + singleEquivMap.put("weo", "tlw"); + singleEquivMap.put("wuu", "zh-wuu"); + singleEquivMap.put("xch", "cmk"); + singleEquivMap.put("yi", "ji"); + singleEquivMap.put("yma", "lrr"); + singleEquivMap.put("yue", "zh-yue"); + singleEquivMap.put("zh-cmn-hans", "cmn-hans"); + singleEquivMap.put("zh-cmn-hant", "cmn-hant"); + singleEquivMap.put("zh-gan", "gan"); + singleEquivMap.put("zh-min-nan", "nan"); + singleEquivMap.put("zh-wuu", "wuu"); + singleEquivMap.put("zh-xiang", "hsn"); + singleEquivMap.put("zh-yue", "yue"); + + multiEquivsMap.put("ccq", new String[] {"rki", "ybd"}); + multiEquivsMap.put("cmn", new String[] {"zh-guoyu", "zh-cmn"}); + multiEquivsMap.put("drw", new String[] {"prs", "tnf"}); + multiEquivsMap.put("hak", new String[] {"i-hak", "zh-hakka"}); + multiEquivsMap.put("i-hak", new String[] {"hak", "zh-hakka"}); + multiEquivsMap.put("mry", new String[] {"mst", "myt"}); + multiEquivsMap.put("mst", new String[] {"mry", "myt"}); + multiEquivsMap.put("myt", new String[] {"mry", "mst"}); + multiEquivsMap.put("prs", new String[] {"drw", "tnf"}); + multiEquivsMap.put("rki", new String[] {"ccq", "ybd"}); + multiEquivsMap.put("tnf", new String[] {"prs", "drw"}); + multiEquivsMap.put("ybd", new String[] {"rki", "ccq"}); + multiEquivsMap.put("zh-cmn", new String[] {"cmn", "zh-guoyu"}); + multiEquivsMap.put("zh-guoyu", new String[] {"cmn", "zh-cmn"}); + multiEquivsMap.put("zh-hakka", new String[] {"hak", "i-hak"}); + + regionVariantEquivMap.put("-alalc97", "-heploc"); + regionVariantEquivMap.put("-bu", "-mm"); + regionVariantEquivMap.put("-cd", "-zr"); + regionVariantEquivMap.put("-dd", "-de"); + regionVariantEquivMap.put("-de", "-dd"); + regionVariantEquivMap.put("-fr", "-fx"); + regionVariantEquivMap.put("-fx", "-fr"); + regionVariantEquivMap.put("-heploc", "-alalc97"); + regionVariantEquivMap.put("-mm", "-bu"); + regionVariantEquivMap.put("-tl", "-tp"); + regionVariantEquivMap.put("-tp", "-tl"); + regionVariantEquivMap.put("-yd", "-ye"); + regionVariantEquivMap.put("-ye", "-yd"); + regionVariantEquivMap.put("-zr", "-cd"); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/locale/LocaleMatcher.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2012, 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 sun.util.locale; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Locale.*; +import static java.util.Locale.FilteringMode.*; +import static java.util.Locale.LanguageRange.*; +import java.util.Map; +import java.util.Set; + +/** + * Implementation for BCP47 Locale matching + * + */ +public final class LocaleMatcher { + + public static List<Locale> filter(List<LanguageRange> priorityList, + Collection<Locale> locales, + FilteringMode mode) { + if (priorityList.isEmpty() || locales.isEmpty()) { + return new ArrayList<>(); // need to return a empty mutable List + } + + // Create a list of language tags to be matched. + List<String> tags = new ArrayList<>(); + for (Locale locale : locales) { + tags.add(locale.toLanguageTag()); + } + + // Filter language tags. + List<String> filteredTags = filterTags(priorityList, tags, mode); + + // Create a list of matching locales. + List<Locale> filteredLocales = new ArrayList<>(filteredTags.size()); + for (String tag : filteredTags) { + filteredLocales.add(Locale.forLanguageTag(tag)); + } + + return filteredLocales; + } + + public static List<String> filterTags(List<LanguageRange> priorityList, + Collection<String> tags, + FilteringMode mode) { + if (priorityList.isEmpty() || tags.isEmpty()) { + return new ArrayList<>(); // need to return a empty mutable List + } + + ArrayList<LanguageRange> list; + if (mode == EXTENDED_FILTERING) { + return filterExtended(priorityList, tags); + } else { + list = new ArrayList<>(); + for (LanguageRange lr : priorityList) { + String range = lr.getRange(); + if (range.startsWith("*-") + || range.indexOf("-*") != -1) { // Extended range + if (mode == AUTOSELECT_FILTERING) { + return filterExtended(priorityList, tags); + } else if (mode == MAP_EXTENDED_RANGES) { + if (range.charAt(0) == '*') { + range = "*"; + } else { + range = range.replaceAll("-[*]", ""); + } + list.add(new LanguageRange(range, lr.getWeight())); + } else if (mode == REJECT_EXTENDED_RANGES) { + throw new IllegalArgumentException("An extended range \"" + + range + + "\" found in REJECT_EXTENDED_RANGES mode."); + } + } else { // Basic range + list.add(lr); + } + } + + return filterBasic(list, tags); + } + } + + private static List<String> filterBasic(List<LanguageRange> priorityList, + Collection<String> tags) { + List<String> list = new ArrayList<>(); + for (LanguageRange lr : priorityList) { + String range = lr.getRange(); + if (range.equals("*")) { + return new ArrayList<String>(tags); + } else { + for (String tag : tags) { + tag = tag.toLowerCase(); + if (tag.startsWith(range)) { + int len = range.length(); + if ((tag.length() == len || tag.charAt(len) == '-') + && !list.contains(tag)) { + list.add(tag); + } + } + } + } + } + + return list; + } + + private static List<String> filterExtended(List<LanguageRange> priorityList, + Collection<String> tags) { + List<String> list = new ArrayList<>(); + for (LanguageRange lr : priorityList) { + String range = lr.getRange(); + if (range.equals("*")) { + return new ArrayList<String>(tags); + } + String[] rangeSubtags = range.split("-"); + for (String tag : tags) { + tag = tag.toLowerCase(); + String[] tagSubtags = tag.split("-"); + if (!rangeSubtags[0].equals(tagSubtags[0]) + && !rangeSubtags[0].equals("*")) { + continue; + } + + int rangeIndex = 1; + int tagIndex = 1; + + while (rangeIndex < rangeSubtags.length + && tagIndex < tagSubtags.length) { + if (rangeSubtags[rangeIndex].equals("*")) { + rangeIndex++; + } else if (rangeSubtags[rangeIndex].equals(tagSubtags[tagIndex])) { + rangeIndex++; + tagIndex++; + } else if (tagSubtags[tagIndex].length() == 1 + && !tagSubtags[tagIndex].equals("*")) { + break; + } else { + tagIndex++; + } + } + + if (rangeSubtags.length == rangeIndex && !list.contains(tag)) { + list.add(tag); + } + } + } + + return list; + } + + public static Locale lookup(List<LanguageRange> priorityList, + Collection<Locale> locales) { + if (priorityList.isEmpty() || locales.isEmpty()) { + return null; + } + + // Create a list of language tags to be matched. + List<String> tags = new ArrayList<>(); + for (Locale locale : locales) { + tags.add(locale.toLanguageTag()); + } + + // Look up a language tags. + String lookedUpTag = lookupTag(priorityList, tags); + + if (lookedUpTag == null) { + return null; + } else { + return Locale.forLanguageTag(lookedUpTag); + } + } + + public static String lookupTag(List<LanguageRange> priorityList, + Collection<String> tags) { + if (priorityList.isEmpty() || tags.isEmpty()) { + return null; + } + + for (LanguageRange lr : priorityList) { + String range = lr.getRange(); + + // Special language range ("*") is ignored in lookup. + if (range.equals("*")) { + continue; + } + + String rangeForRegex = range.replaceAll("\\x2A", "\\\\p{Alnum}*"); + while (rangeForRegex.length() > 0) { + for (String tag : tags) { + tag = tag.toLowerCase(); + if (tag.matches(rangeForRegex)) { + return tag; + } + } + + // Truncate from the end.... + int index = rangeForRegex.lastIndexOf('-'); + if (index >= 0) { + rangeForRegex = rangeForRegex.substring(0, index); + + // if range ends with an extension key, truncate it. + if (rangeForRegex.lastIndexOf('-') == rangeForRegex.length()-2) { + rangeForRegex = + rangeForRegex.substring(0, rangeForRegex.length()-2); + } + } else { + rangeForRegex = ""; + } + } + } + + return null; + } + + public static List<LanguageRange> parse(String ranges) { + ranges = ranges.replaceAll(" ", "").toLowerCase(); + if (ranges.startsWith("accept-language:")) { + ranges = ranges.substring(16); // delete unnecessary prefix + } + + String[] langRanges = ranges.split(","); + List<LanguageRange> list = new ArrayList<>(langRanges.length); + List<String> tempList = new ArrayList<>(); + int numOfRanges = 0; + + for (String range : langRanges) { + int index; + String r; + double w; + + if ((index = range.indexOf(";q=")) == -1) { + r = range; + w = MAX_WEIGHT; + } else { + r = range.substring(0, index); + index += 3; + try { + w = Double.parseDouble(range.substring(index)); + } + catch (Exception e) { + throw new IllegalArgumentException("weight=\"" + + range.substring(index) + + "\" for language range \"" + r + "\""); + } + + if (w < MIN_WEIGHT || w > MAX_WEIGHT) { + throw new IllegalArgumentException("weight=" + w + + " for language range \"" + r + + "\". It must be between " + MIN_WEIGHT + + " and " + MAX_WEIGHT + "."); + } + } + + if (!tempList.contains(r)) { + LanguageRange lr = new LanguageRange(r, w); + index = numOfRanges; + for (int j = 0; j < numOfRanges; j++) { + if (list.get(j).getWeight() < w) { + index = j; + break; + } + } + list.add(index, lr); + numOfRanges++; + tempList.add(r); + + // Check if the range has an equivalent using IANA LSR data. + // If yes, add it to the User's Language Priority List as well. + + // aa-XX -> aa-YY + String equivalent; + if ((equivalent = getEquivalentForRegionAndVariant(r)) != null + && !tempList.contains(equivalent)) { + list.add(index+1, new LanguageRange(equivalent, w)); + numOfRanges++; + tempList.add(equivalent); + } + + String[] equivalents; + if ((equivalents = getEquivalentsForLanguage(r)) != null) { + for (String equiv: equivalents) { + // aa-XX -> bb-XX(, cc-XX) + if (!tempList.contains(equiv)) { + list.add(index+1, new LanguageRange(equiv, w)); + numOfRanges++; + tempList.add(equiv); + } + + // bb-XX -> bb-YY(, cc-YY) + equivalent = getEquivalentForRegionAndVariant(equiv); + if (equivalent != null + && !tempList.contains(equivalent)) { + list.add(index+1, new LanguageRange(equivalent, w)); + numOfRanges++; + tempList.add(equivalent); + } + } + } + } + } + + return list; + } + + private static String[] getEquivalentsForLanguage(String range) { + String r = range; + + while (r.length() > 0) { + if (LocaleEquivalentMaps.singleEquivMap.containsKey(r)) { + String equiv = LocaleEquivalentMaps.singleEquivMap.get(r); + // Return immediately for performance if the first matching + // subtag is found. + return new String[] {range.replaceFirst(r, equiv)}; + } else if (LocaleEquivalentMaps.multiEquivsMap.containsKey(r)) { + String[] equivs = LocaleEquivalentMaps.multiEquivsMap.get(r); + for (int i = 0; i < equivs.length; i++) { + equivs[i] = range.replaceFirst(r, equivs[i]); + } + return equivs; + } + + // Truncate the last subtag simply. + int index = r.lastIndexOf('-'); + if (index == -1) { + break; + } + r = r.substring(0, index); + } + + return null; + } + + private static String getEquivalentForRegionAndVariant(String range) { + int extensionKeyIndex = getExtentionKeyIndex(range); + + for (String subtag : LocaleEquivalentMaps.regionVariantEquivMap.keySet()) { + int index; + if ((index = range.indexOf(subtag)) != -1) { + // Check if the matching text is a valid region or variant. + if (extensionKeyIndex != Integer.MIN_VALUE + && index > extensionKeyIndex) { + continue; + } + + int len = index + subtag.length(); + if (range.length() == len || range.charAt(len) == '-') { + return range.replaceFirst(subtag, LocaleEquivalentMaps.regionVariantEquivMap.get(subtag)); + } + } + } + + return null; + } + + private static int getExtentionKeyIndex(String s) { + char[] c = s.toCharArray(); + int index = Integer.MIN_VALUE; + for (int i = 1; i < c.length; i++) { + if (c[i] == '-') { + if (i - index == 2) { + return index; + } else { + index = i; + } + } + } + return Integer.MIN_VALUE; + } + + public static List<LanguageRange> mapEquivalents( + List<LanguageRange>priorityList, + Map<String, List<String>> map) { + if (priorityList.isEmpty()) { + return new ArrayList<>(); // need to return a empty mutable List + } + if (map == null || map.isEmpty()) { + return new ArrayList<LanguageRange>(priorityList); + } + + // Create a map, key=originalKey.toLowerCaes(), value=originalKey + Map<String, String> keyMap = new HashMap<>(); + for (String key : map.keySet()) { + keyMap.put(key.toLowerCase(), key); + } + + List<LanguageRange> list = new ArrayList<>(); + for (LanguageRange lr : priorityList) { + String range = lr.getRange(); + String r = range; + boolean hasEquivalent = false; + + while (r.length() > 0) { + if (keyMap.containsKey(r)) { + hasEquivalent = true; + List<String> equivalents = map.get(keyMap.get(r)); + if (equivalents != null) { + int len = r.length(); + for (String equivalent : equivalents) { + list.add(new LanguageRange(equivalent.toLowerCase() + + range.substring(len), + lr.getWeight())); + } + } + // Return immediately if the first matching subtag is found. + break; + } + + // Truncate the last subtag simply. + int index = r.lastIndexOf('-'); + if (index == -1) { + break; + } + r = r.substring(0, index); + } + + if (!hasEquivalent) { + list.add(lr); + } + } + + return list; + } + + private LocaleMatcher() {} + +}
--- a/src/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Thu Oct 11 16:59:50 2012 -0700 @@ -137,7 +137,7 @@ @Override public boolean isSupportedLocale(Locale locale) { - if (locale == Locale.ROOT) { + if (Locale.ROOT.equals(locale)) { return true; } String calendarType = null;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 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 sun.util.locale.provider; + +/** + * FallbackProviderAdapter implementation. + * + * @author Naoto Sato + */ +public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter { + + /** + * Returns the type of this LocaleProviderAdapter + */ + @Override + public LocaleProviderAdapter.Type getAdapterType() { + return Type.FALLBACK; + } +}
--- a/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Thu Oct 11 16:59:50 2012 -0700 @@ -71,7 +71,7 @@ */ @Override public LocaleProviderAdapter.Type getAdapterType() { - return LocaleProviderAdapter.Type.JRE; + return Type.JRE; } /** @@ -125,7 +125,7 @@ public BreakIteratorProvider getBreakIteratorProvider() { if (breakIteratorProvider == null) { BreakIteratorProvider provider = new BreakIteratorProviderImpl(getAdapterType(), - getLanguateTagSet("FormatData")); + getLanguageTagSet("FormatData")); synchronized (this) { if (breakIteratorProvider == null) { breakIteratorProvider = provider; @@ -139,7 +139,7 @@ public CollatorProvider getCollatorProvider() { if (collatorProvider == null) { CollatorProvider provider = new CollatorProviderImpl(getAdapterType(), - getLanguateTagSet("CollationData")); + getLanguageTagSet("CollationData")); synchronized (this) { if (collatorProvider == null) { collatorProvider = provider; @@ -153,7 +153,7 @@ public DateFormatProvider getDateFormatProvider() { if (dateFormatProvider == null) { DateFormatProvider provider = new DateFormatProviderImpl(getAdapterType(), - getLanguateTagSet("FormatData")); + getLanguageTagSet("FormatData")); synchronized (this) { if (dateFormatProvider == null) { dateFormatProvider = provider; @@ -167,7 +167,7 @@ public DateFormatSymbolsProvider getDateFormatSymbolsProvider() { if (dateFormatSymbolsProvider == null) { DateFormatSymbolsProvider provider = new DateFormatSymbolsProviderImpl(getAdapterType(), - getLanguateTagSet("FormatData")); + getLanguageTagSet("FormatData")); synchronized (this) { if (dateFormatSymbolsProvider == null) { dateFormatSymbolsProvider = provider; @@ -180,7 +180,7 @@ @Override public DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() { if (decimalFormatSymbolsProvider == null) { - DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl(getAdapterType(), getLanguateTagSet("FormatData")); + DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl(getAdapterType(), getLanguageTagSet("FormatData")); synchronized (this) { if (decimalFormatSymbolsProvider == null) { decimalFormatSymbolsProvider = provider; @@ -194,7 +194,7 @@ public NumberFormatProvider getNumberFormatProvider() { if (numberFormatProvider == null) { NumberFormatProvider provider = new NumberFormatProviderImpl(getAdapterType(), - getLanguateTagSet("FormatData")); + getLanguageTagSet("FormatData")); synchronized (this) { if (numberFormatProvider == null) { numberFormatProvider = provider; @@ -211,7 +211,7 @@ public CurrencyNameProvider getCurrencyNameProvider() { if (currencyNameProvider == null) { CurrencyNameProvider provider = new CurrencyNameProviderImpl(getAdapterType(), - getLanguateTagSet("CurrencyNames")); + getLanguageTagSet("CurrencyNames")); synchronized (this) { if (currencyNameProvider == null) { currencyNameProvider = provider; @@ -225,7 +225,7 @@ public LocaleNameProvider getLocaleNameProvider() { if (localeNameProvider == null) { LocaleNameProvider provider = new LocaleNameProviderImpl(getAdapterType(), - getLanguateTagSet("LocaleNames")); + getLanguageTagSet("LocaleNames")); synchronized (this) { if (localeNameProvider == null) { localeNameProvider = provider; @@ -239,7 +239,7 @@ public TimeZoneNameProvider getTimeZoneNameProvider() { if (timeZoneNameProvider == null) { TimeZoneNameProvider provider = new TimeZoneNameProviderImpl(getAdapterType(), - getLanguateTagSet("TimeZoneNames")); + getLanguageTagSet("TimeZoneNames")); synchronized (this) { if (timeZoneNameProvider == null) { timeZoneNameProvider = provider; @@ -253,8 +253,8 @@ public CalendarDataProvider getCalendarDataProvider() { if (calendarDataProvider == null) { Set<String> set = new HashSet<>(); - set.addAll(getLanguateTagSet("FormatData")); - set.addAll(getLanguateTagSet("CalendarData")); + set.addAll(getLanguageTagSet("FormatData")); + set.addAll(getLanguageTagSet("CalendarData")); CalendarDataProvider provider = new CalendarDataProviderImpl(getAdapterType(), set); synchronized (this) { @@ -302,7 +302,7 @@ return AvailableJRELocales.localeList.clone(); } - public Set<String> getLanguateTagSet(String category) { + public Set<String> getLanguageTagSet(String category) { Set<String> tagset = langtagSets.get(category); if (tagset == null) { tagset = createLanguageTagSet(category); @@ -328,6 +328,10 @@ } tagset.add(token); } + + // ensure en-US is there (mandated by the spec, e.g. Collator.getAvailableLocales()) + tagset.add("en-US"); + return tagset; }
--- a/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Thu Oct 11 16:59:50 2012 -0700 @@ -59,7 +59,8 @@ JRE("sun.util.resources", "sun.text.resources"), CLDR("sun.util.resources.cldr", "sun.text.resources.cldr"), SPI, - HOST; + HOST, + FALLBACK("sun.util.resources", "sun.text.resources"); private final String UTIL_RESOURCES_PACKAGE; private final String TEXT_RESOURCES_PACKAGE; @@ -111,41 +112,49 @@ */ private static LocaleProviderAdapter hostLocaleProviderAdapter = null; + /** + * FALLBACK Locale Data Adapter instance. It's basically the same with JRE, but only kicks + * in for the root locale. + */ + private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null; + static { String order = AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.locale.providers")); - // Override adapterPreference with the properties one - if (order != null && order.length() != 0) { - String[] types = order.split(","); - List<Type> typeList = new ArrayList<>(); - for (String type : types) { - try { - Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT)); + // Override adapterPreference with the properties one + if (order != null && order.length() != 0) { + String[] types = order.split(","); + List<Type> typeList = new ArrayList<>(); + for (String type : types) { + try { + Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT)); - // load adapter if necessary - switch (aType) { - case CLDR: - cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter(); - break; - case HOST: - hostLocaleProviderAdapter = new HostLocaleProviderAdapter(); - break; - } - typeList.add(aType); - } catch (// could be caused by the user specifying wrong - // provider name or format in the system property - IllegalArgumentException | - UnsupportedOperationException e) { - LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString()); - } - } + // load adapter if necessary + switch (aType) { + case CLDR: + cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter(); + break; + case HOST: + hostLocaleProviderAdapter = new HostLocaleProviderAdapter(); + break; + } + typeList.add(aType); + } catch (IllegalArgumentException | UnsupportedOperationException e) { + // could be caused by the user specifying wrong + // provider name or format in the system property + LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString()); + } + } - if (!typeList.contains(Type.JRE)) { - // Append JRE as the last resort. - typeList.add(Type.JRE); - } - adapterPreference = typeList.toArray(new Type[0]); - } + if (!typeList.isEmpty()) { + if (!typeList.contains(Type.JRE)) { + // Append FALLBACK as the last resort. + fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter(); + typeList.add(Type.FALLBACK); + } + adapterPreference = typeList.toArray(new Type[0]); + } + } } @@ -162,6 +171,8 @@ return spiLocaleProviderAdapter; case HOST: return hostLocaleProviderAdapter; + case FALLBACK: + return fallbackLocaleProviderAdapter; default: throw new InternalError("unknown locale data adapter type"); } @@ -173,7 +184,7 @@ public static LocaleProviderAdapter getResourceBundleBased() { for (Type type : getAdapterPreference()) { - if (type == Type.JRE || type == Type.CLDR) { + if (type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK) { return forType(type); } } @@ -218,8 +229,8 @@ } } - // returns the adapter for JRE as the last resort - return jreLocaleProviderAdapter; + // returns the adapter for FALLBACK as the last resort + return fallbackLocaleProviderAdapter; } private static LocaleProviderAdapter findAdapter(Class<? extends LocaleServiceProvider> providerClass, @@ -238,18 +249,24 @@ /** * A utility method for implementing the default LocaleServiceProvider.isSupportedLocale - * for the JRE and CLDR adapters. + * for the JRE, CLDR, and FALLBACK adapters. */ static boolean isSupportedLocale(Locale locale, LocaleProviderAdapter.Type type, Set<String> langtags) { - assert type == Type.JRE || type == Type.CLDR; - if (locale == Locale.ROOT) { + assert type == Type.JRE || type == Type.CLDR || type == Type.FALLBACK; + if (Locale.ROOT.equals(locale)) { return true; } + + if (type == Type.FALLBACK) { + // no other locales except ROOT are supported for FALLBACK + return false; + } + locale = locale.stripExtensions(); if (langtags.contains(locale.toLanguageTag())) { return true; } - if (type == LocaleProviderAdapter.Type.JRE) { + if (type == Type.JRE) { String oldname = locale.toString().replace('_', '-'); return langtags.contains(oldname); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/spi/XmlPropertiesProvider.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012, 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 sun.util.spi; + +import java.util.Properties; +import java.util.InvalidPropertiesFormatException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * Service-provider class for loading and storing {@link Properites} in XML + * format. + * + * @see Properties#loadFromXML + * @see Properties#storeToXML + */ + +public abstract class XmlPropertiesProvider { + + /** + * Initializes a new instance of this class. + */ + protected XmlPropertiesProvider() { + // do nothing for now + } + + /** + * Loads all of the properties represented by the XML document on the + * specified input stream into a properties table. + * + * @param props the properties table to populate + * @param in the input stream from which to read the XML document + * @throws IOException if reading from the specified input stream fails + * @throws InvalidPropertiesFormatException Data on input stream does not + * constitute a valid XML document with the mandated document type. + * + * @see Properties#loadFromXML + */ + public abstract void load(Properties props, InputStream in) + throws IOException, InvalidPropertiesFormatException; + + /** + * Emits an XML document representing all of the properties in a given + * table. + * + * @param props the properies to store + * @param out the output stream on which to emit the XML document. + * @param comment a description of the property list, can be @{code null} + * @param encoding the name of a supported character encoding + * + * @throws IOException if writing to the specified output stream fails + * @throws NullPointerException if {@code out} is null. + * @throws ClassCastException if this {@code Properties} object + * contains any keys or values that are not + * {@code Strings}. + * + * @see Properties#storeToXML + */ + public abstract void store(Properties props, OutputStream out, + String comment, String encoding) + throws IOException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/xml/META-INF/services/sun.util.spi.XmlPropertiesProvider Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,1 @@ +sun.util.xml.PlatformXmlPropertiesProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/util/xml/PlatformXmlPropertiesProvider.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2003, 2011, 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 sun.util.xml; + +import java.io.*; +import java.util.*; +import org.xml.sax.*; +import org.w3c.dom.*; +import javax.xml.parsers.*; +import javax.xml.transform.*; +import javax.xml.transform.dom.*; +import javax.xml.transform.stream.*; + +import sun.util.spi.XmlPropertiesProvider; + +/** + * A {@code XmlPropertiesProvider} implementation that uses the JAXP API + * for parsing. + * + * @author Michael McCloskey + * @since 1.3 + */ +public class PlatformXmlPropertiesProvider extends XmlPropertiesProvider { + + // XML loading and saving methods for Properties + + // The required DTD URI for exported properties + private static final String PROPS_DTD_URI = + "http://java.sun.com/dtd/properties.dtd"; + + private static final String PROPS_DTD = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<!-- DTD for properties -->" + + "<!ELEMENT properties ( comment?, entry* ) >"+ + "<!ATTLIST properties" + + " version CDATA #FIXED \"1.0\">" + + "<!ELEMENT comment (#PCDATA) >" + + "<!ELEMENT entry (#PCDATA) >" + + "<!ATTLIST entry " + + " key CDATA #REQUIRED>"; + + /** + * Version number for the format of exported properties files. + */ + private static final String EXTERNAL_XML_VERSION = "1.0"; + + @Override + public void load(Properties props, InputStream in) + throws IOException, InvalidPropertiesFormatException + { + Document doc = null; + try { + doc = getLoadingDoc(in); + } catch (SAXException saxe) { + throw new InvalidPropertiesFormatException(saxe); + } + Element propertiesElement = doc.getDocumentElement(); + String xmlVersion = propertiesElement.getAttribute("version"); + if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) + throw new InvalidPropertiesFormatException( + "Exported Properties file format version " + xmlVersion + + " is not supported. This java installation can read" + + " versions " + EXTERNAL_XML_VERSION + " or older. You" + + " may need to install a newer version of JDK."); + importProperties(props, propertiesElement); + } + + static Document getLoadingDoc(InputStream in) + throws SAXException, IOException + { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setIgnoringElementContentWhitespace(true); + dbf.setValidating(true); + dbf.setCoalescing(true); + dbf.setIgnoringComments(true); + try { + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setEntityResolver(new Resolver()); + db.setErrorHandler(new EH()); + InputSource is = new InputSource(in); + return db.parse(is); + } catch (ParserConfigurationException x) { + throw new Error(x); + } + } + + static void importProperties(Properties props, Element propertiesElement) { + NodeList entries = propertiesElement.getChildNodes(); + int numEntries = entries.getLength(); + int start = numEntries > 0 && + entries.item(0).getNodeName().equals("comment") ? 1 : 0; + for (int i=start; i<numEntries; i++) { + Element entry = (Element)entries.item(i); + if (entry.hasAttribute("key")) { + Node n = entry.getFirstChild(); + String val = (n == null) ? "" : n.getNodeValue(); + props.setProperty(entry.getAttribute("key"), val); + } + } + } + + @Override + public void store(Properties props, OutputStream os, String comment, + String encoding) + throws IOException + { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = null; + try { + db = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException pce) { + assert(false); + } + Document doc = db.newDocument(); + Element properties = (Element) + doc.appendChild(doc.createElement("properties")); + + if (comment != null) { + Element comments = (Element)properties.appendChild( + doc.createElement("comment")); + comments.appendChild(doc.createTextNode(comment)); + } + + synchronized (props) { + for (String key : props.stringPropertyNames()) { + Element entry = (Element)properties.appendChild( + doc.createElement("entry")); + entry.setAttribute("key", key); + entry.appendChild(doc.createTextNode(props.getProperty(key))); + } + } + emitDocument(doc, os, encoding); + } + + static void emitDocument(Document doc, OutputStream os, String encoding) + throws IOException + { + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer t = null; + try { + t = tf.newTransformer(); + t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI); + t.setOutputProperty(OutputKeys.INDENT, "yes"); + t.setOutputProperty(OutputKeys.METHOD, "xml"); + t.setOutputProperty(OutputKeys.ENCODING, encoding); + } catch (TransformerConfigurationException tce) { + assert(false); + } + DOMSource doms = new DOMSource(doc); + StreamResult sr = new StreamResult(os); + try { + t.transform(doms, sr); + } catch (TransformerException te) { + throw new IOException(te); + } + } + + private static class Resolver implements EntityResolver { + public InputSource resolveEntity(String pid, String sid) + throws SAXException + { + if (sid.equals(PROPS_DTD_URI)) { + InputSource is; + is = new InputSource(new StringReader(PROPS_DTD)); + is.setSystemId(PROPS_DTD_URI); + return is; + } + throw new SAXException("Invalid system identifier: " + sid); + } + } + + private static class EH implements ErrorHandler { + public void error(SAXParseException x) throws SAXException { + throw x; + } + public void fatalError(SAXParseException x) throws SAXException { + throw x; + } + public void warning(SAXParseException x) throws SAXException { + throw x; + } + } + +}
--- a/src/share/classes/sun/util/xml/XMLUtils.java Thu Oct 11 09:50:14 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2003, 2011, 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 sun.util.xml; - -import java.io.*; -import java.util.*; -import org.xml.sax.*; -import org.xml.sax.helpers.*; -import org.w3c.dom.*; -import javax.xml.parsers.*; -import javax.xml.transform.*; -import javax.xml.transform.dom.*; -import javax.xml.transform.stream.*; - -/** - * A class used to aid in Properties load and save in XML. Keeping this - * code outside of Properties helps reduce the number of classes loaded - * when Properties is loaded. - * - * @author Michael McCloskey - * @since 1.3 - */ -public class XMLUtils { - - // XML loading and saving methods for Properties - - // The required DTD URI for exported properties - private static final String PROPS_DTD_URI = - "http://java.sun.com/dtd/properties.dtd"; - - private static final String PROPS_DTD = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<!-- DTD for properties -->" + - "<!ELEMENT properties ( comment?, entry* ) >"+ - "<!ATTLIST properties" + - " version CDATA #FIXED \"1.0\">" + - "<!ELEMENT comment (#PCDATA) >" + - "<!ELEMENT entry (#PCDATA) >" + - "<!ATTLIST entry " + - " key CDATA #REQUIRED>"; - - /** - * Version number for the format of exported properties files. - */ - private static final String EXTERNAL_XML_VERSION = "1.0"; - - public static void load(Properties props, InputStream in) - throws IOException, InvalidPropertiesFormatException - { - Document doc = null; - try { - doc = getLoadingDoc(in); - } catch (SAXException saxe) { - throw new InvalidPropertiesFormatException(saxe); - } - Element propertiesElement = doc.getDocumentElement(); - String xmlVersion = propertiesElement.getAttribute("version"); - if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) - throw new InvalidPropertiesFormatException( - "Exported Properties file format version " + xmlVersion + - " is not supported. This java installation can read" + - " versions " + EXTERNAL_XML_VERSION + " or older. You" + - " may need to install a newer version of JDK."); - importProperties(props, propertiesElement); - } - - static Document getLoadingDoc(InputStream in) - throws SAXException, IOException - { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setIgnoringElementContentWhitespace(true); - dbf.setValidating(true); - dbf.setCoalescing(true); - dbf.setIgnoringComments(true); - try { - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setEntityResolver(new Resolver()); - db.setErrorHandler(new EH()); - InputSource is = new InputSource(in); - return db.parse(is); - } catch (ParserConfigurationException x) { - throw new Error(x); - } - } - - static void importProperties(Properties props, Element propertiesElement) { - NodeList entries = propertiesElement.getChildNodes(); - int numEntries = entries.getLength(); - int start = numEntries > 0 && - entries.item(0).getNodeName().equals("comment") ? 1 : 0; - for (int i=start; i<numEntries; i++) { - Element entry = (Element)entries.item(i); - if (entry.hasAttribute("key")) { - Node n = entry.getFirstChild(); - String val = (n == null) ? "" : n.getNodeValue(); - props.setProperty(entry.getAttribute("key"), val); - } - } - } - - public static void save(Properties props, OutputStream os, String comment, - String encoding) - throws IOException - { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = null; - try { - db = dbf.newDocumentBuilder(); - } catch (ParserConfigurationException pce) { - assert(false); - } - Document doc = db.newDocument(); - Element properties = (Element) - doc.appendChild(doc.createElement("properties")); - - if (comment != null) { - Element comments = (Element)properties.appendChild( - doc.createElement("comment")); - comments.appendChild(doc.createTextNode(comment)); - } - - synchronized (props) { - for (String key : props.stringPropertyNames()) { - Element entry = (Element)properties.appendChild( - doc.createElement("entry")); - entry.setAttribute("key", key); - entry.appendChild(doc.createTextNode(props.getProperty(key))); - } - } - emitDocument(doc, os, encoding); - } - - static void emitDocument(Document doc, OutputStream os, String encoding) - throws IOException - { - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer t = null; - try { - t = tf.newTransformer(); - t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI); - t.setOutputProperty(OutputKeys.INDENT, "yes"); - t.setOutputProperty(OutputKeys.METHOD, "xml"); - t.setOutputProperty(OutputKeys.ENCODING, encoding); - } catch (TransformerConfigurationException tce) { - assert(false); - } - DOMSource doms = new DOMSource(doc); - StreamResult sr = new StreamResult(os); - try { - t.transform(doms, sr); - } catch (TransformerException te) { - IOException ioe = new IOException(); - ioe.initCause(te); - throw ioe; - } - } - - private static class Resolver implements EntityResolver { - public InputSource resolveEntity(String pid, String sid) - throws SAXException - { - if (sid.equals(PROPS_DTD_URI)) { - InputSource is; - is = new InputSource(new StringReader(PROPS_DTD)); - is.setSystemId(PROPS_DTD_URI); - return is; - } - throw new SAXException("Invalid system identifier: " + sid); - } - } - - private static class EH implements ErrorHandler { - public void error(SAXParseException x) throws SAXException { - throw x; - } - public void fatalError(SAXParseException x) throws SAXException { - throw x; - } - public void warning(SAXParseException x) throws SAXException { - throw x; - } - } - -}
--- a/src/share/test/pack200/pack.conf Thu Oct 11 09:50:14 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# Copyright (c) 2003, 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. -# -# -# The config file for the packer, define all the test properties here. -pack.effort=1 -pack.unknown.attribute=error -pack.deflate.hint=false -pack.keep.class.order=true -pack.verbose=1 -
--- a/src/solaris/classes/sun/java2d/xr/XRDrawImage.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/classes/sun/java2d/xr/XRDrawImage.java Thu Oct 11 16:59:50 2012 -0700 @@ -27,6 +27,7 @@ import java.awt.*; import java.awt.geom.*; +import java.awt.image.*; import sun.java2d.*; import sun.java2d.loops.*; @@ -45,8 +46,8 @@ SurfaceData srcData = dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor); - if (srcData != null && !isBgOperation(srcData, bgColor)) { // TODO: Do we bail out on bgBlits? - // && srcData instanceof XRSurfaceData) { + if (srcData != null && !isBgOperation(srcData, bgColor) + && interpType <= AffineTransformOp.TYPE_BILINEAR) { SurfaceType srcType = srcData.getSurfaceType(); SurfaceType dstType = dstData.getSurfaceType();
--- a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java Thu Oct 11 16:59:50 2012 -0700 @@ -68,7 +68,7 @@ static final short REVENT_OFFSET = 6; // Special value to indicate that an update should be ignored - static final byte CANCELLED = (byte)-1; + static final byte IGNORE = (byte)-1; // Maximum number of open file descriptors static final int OPEN_MAX = IOUtil.fdLimit(); @@ -192,15 +192,15 @@ // events are stored as bytes for efficiency reasons byte b = (byte)mask; - assert (b == mask) && (b != CANCELLED); + assert (b == mask) && (b != IGNORE); setUpdateEvents(fd, b); } } void release(int fd) { synchronized (updateLock) { - // cancel any pending update for this file descriptor - setUpdateEvents(fd, CANCELLED); + // ignore any pending update for this file descriptor + setUpdateEvents(fd, IGNORE); // remove from /dev/poll if (registered.get(fd)) { @@ -236,32 +236,40 @@ while (j < updateCount) { int fd = updateDescriptors[j]; short events = getUpdateEvents(fd); - boolean isRegistered = registered.get(fd); + boolean wasRegistered = registered.get(fd); // events = 0 => POLLREMOVE or do-nothing - if (events != CANCELLED) { + if (events != IGNORE) { if (events == 0) { - if (isRegistered) { + if (wasRegistered) { events = POLLREMOVE; registered.clear(fd); } else { - events = CANCELLED; + events = IGNORE; } } else { - if (!isRegistered) { + if (!wasRegistered) { registered.set(fd); } } } // populate pollfd array with updated event - if (events != CANCELLED) { + if (events != IGNORE) { + // insert POLLREMOVE if changing events + if (wasRegistered && events != POLLREMOVE) { + putPollFD(pollArray, index, fd, POLLREMOVE); + index++; + } putPollFD(pollArray, index, fd, events); index++; - if (index >= NUM_POLLFDS) { + if (index >= (NUM_POLLFDS-1)) { registerMultiple(wfd, pollArray.address(), index); index = 0; } + + // events for this fd now up to date + setUpdateEvents(fd, IGNORE); } j++; }
--- a/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012, 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 @@ -145,6 +145,9 @@ } return xattrEnabled; } + // POSIX attributes not supported on FAT + if (type == PosixFileAttributeView.class && entry().fstype().equals("vfat")) + return false; return super.supportsFileAttributeView(type); }
--- a/src/solaris/native/java/net/Inet4AddressImpl.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/Inet4AddressImpl.c Thu Oct 11 16:59:50 2012 -0700 @@ -647,9 +647,10 @@ #ifdef __linux__ if (errno != EINVAL && errno != EHOSTUNREACH) /* - * On some Linuxes, when bound to the loopback interface, sendto - * will fail and errno will be set to EINVAL or EHOSTUNREACH. - * When that happens, don't throw an exception, just return false. + * On some Linux versions, when a socket is bound to the loopback + * interface, sendto will fail and errno will be set to + * EINVAL or EHOSTUNREACH. When that happens, don't throw an + * exception, just return false. */ #endif /*__linux__ */ NET_ThrowNew(env, errno, "Can't send ICMP packet"); @@ -813,9 +814,10 @@ case EINVAL: case EHOSTUNREACH: /* - * On some Linuxes, when bound to the loopback interface, connect - * will fail and errno will be set to EINVAL or EHOSTUNREACH. - * When that happens, don't throw an exception, just return false. + * On some Linux versions, when a socket is bound to the loopback + * interface, connect will fail and errno will be set to EINVAL + * or EHOSTUNREACH. When that happens, don't throw an exception, + * just return false. */ #endif /* __linux__ */ close(fd);
--- a/src/solaris/native/java/net/Inet6AddressImpl.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c Thu Oct 11 16:59:50 2012 -0700 @@ -336,13 +336,7 @@ } (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); -#ifdef __linux__ - if (!kernelIsV22()) { - scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id; - } -#else scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id; -#endif if (scope != 0) { /* zero is default value, no need to set */ (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); @@ -507,8 +501,9 @@ #ifdef __linux__ if (errno != EINVAL && errno != EHOSTUNREACH) /* - * On some Linuxes, when bound to the loopback interface, sendto - * will fail and errno will be set to EINVAL or EHOSTUNREACH. + * On some Linux versions, when a socket is bound to the + * loopback interface, sendto will fail and errno will be + * set to EINVAL or EHOSTUNREACH. * When that happens, don't throw an exception, just return false. */ #endif /*__linux__ */ @@ -623,7 +618,7 @@ * If we can create a RAW socket, then when can use the ICMP ECHO_REQUEST * otherwise we'll try a tcp socket to the Echo port (7). * Note that this is empiric, and not connecting could mean it's blocked - * or the echo servioe has been disabled. + * or the echo service has been disabled. */ fd = JVM_Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); @@ -680,9 +675,10 @@ case EINVAL: case EHOSTUNREACH: /* - * On some Linuxes, when bound to the loopback interface, connect - * will fail and errno will be set to EINVAL or EHOSTUNREACH. - * When that happens, don't throw an exception, just return false. + * On some Linux versions, when a socket is bound to the + * loopback interface, connect will fail and errno will + * be set to EINVAL or EHOSTUNREACH. When that happens, + * don't throw an exception, just return false. */ #endif /* __linux__ */ close(fd);
--- a/src/solaris/native/java/net/NetworkInterface.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/NetworkInterface.c Thu Oct 11 16:59:50 2012 -0700 @@ -769,14 +769,14 @@ return NULL; } - /* return partial list if exception occure in the middle of process ???*/ + /* return partial list if an exception occurs in the middle of process ???*/ /* * If IPv6 is available then enumerate IPv6 addresses. */ #ifdef AF_INET6 - /* User can disable ipv6 expicitly by -Djava.net.preferIPv4Stack=true, + /* User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true, * so we have to call ipv6_available() */ if (ipv6_available()) { @@ -887,7 +887,7 @@ addrP->next = 0; if (family == AF_INET) { /* - * Deal with brodcast addr & subnet mask + * Deal with broadcast addr & subnet mask */ struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size); addrP->brdcast = getBroadcast(env, sock, name, brdcast_to ); @@ -898,7 +898,7 @@ } /** - * Deal with virtual interface with colon notaion e.g. eth0:1 + * Deal with virtual interface with colon notation e.g. eth0:1 */ name_colonP = strchr(name, ':'); if (name_colonP != NULL) { @@ -1327,13 +1327,13 @@ } /** - * Solaris requires that we have IPv6 socket to query an - * interface without IPv4 address - check it here - * POSIX 1 require the kernell to return ENOTTY if the call is - * unappropriate for device e.g. NETMASK for device having IPv6 - * only address but not all devices follows the standart so - * fallback on any error. It's not an ecology friendly but more - * reliable. + * Solaris requires that we have an IPv6 socket to query an + * interface without an IPv4 address - check it here. + * POSIX 1 require the kernel to return ENOTTY if the call is + * inappropriate for a device e.g. the NETMASK for a device having IPv6 + * only address but not all devices follow the standard so + * fall back on any error. It's not an ecologically friendly gesture + * but more reliable. */ if (! alreadyV6 ){ @@ -1359,7 +1359,7 @@ /* * Enumerates and returns all IPv4 interfaces - * (linux verison) + * (linux verision) */ static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c Thu Oct 11 16:59:50 2012 -0700 @@ -73,16 +73,6 @@ static jfieldID pdsi_connectedAddress; static jfieldID pdsi_connectedPort; -#ifdef __linux__ -static jboolean isOldKernel; -#endif - -#if defined(__linux__) && defined(AF_INET6) -static jfieldID pdsi_multicastInterfaceID; -static jfieldID pdsi_loopbackID; -static jfieldID pdsi_ttlID; -#endif - extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him); extern int getDefaultScopeID(JNIEnv *env); @@ -174,41 +164,6 @@ Java_java_net_Inet6Address_init(env, 0); Java_java_net_NetworkInterface_init(env, 0); -#ifdef __linux__ - /* - * We need to determine if this is a 2.2 kernel. - */ - if (uname(&sysinfo) == 0) { - sysinfo.release[3] = '\0'; - isOldKernel = (strcmp(sysinfo.release, "2.2") == 0); - } else { - /* - * uname failed - move to plan B and examine /proc/version - * If this fails assume that /proc has changed and that - * this must be new /proc format and hence new kernel. - */ - FILE *fP; - isOldKernel = JNI_FALSE; - if ((fP = fopen("/proc/version", "r")) != NULL) { - char ver[25]; - if (fgets(ver, sizeof(ver), fP) != NULL) { - isOldKernel = (strstr(ver, "2.2.") != NULL); - } - fclose(fP); - } - } - -#ifdef AF_INET6 - pdsi_multicastInterfaceID = (*env)->GetFieldID(env, cls, "multicastInterface", "I"); - CHECK_NULL(pdsi_multicastInterfaceID); - pdsi_loopbackID = (*env)->GetFieldID(env, cls, "loopbackMode", "Z"); - CHECK_NULL(pdsi_loopbackID); - pdsi_ttlID = (*env)->GetFieldID(env, cls, "ttl", "I"); - CHECK_NULL(pdsi_ttlID); -#endif - -#endif - } /* @@ -257,7 +212,7 @@ return; } - /* intialize the local port */ + /* initialize the local port */ if (localport == 0) { /* Now that we're a connected socket, let's extract the port number * that the system chose for us and store it in the Socket object. @@ -308,20 +263,14 @@ return; } -#ifdef __linux__ - if (isOldKernel) { - int t = 0; - setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (char*) &t, sizeof(int)); - } else -#endif setDefaultScopeID(env, (struct sockaddr *)&rmtaddr); - { - if (JVM_Connect(fd, (struct sockaddr *)&rmtaddr, len) == -1) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException", - "Connect failed"); - return; - } + + if (JVM_Connect(fd, (struct sockaddr *)&rmtaddr, len) == -1) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException", + "Connect failed"); + return; } + } /* @@ -347,12 +296,6 @@ fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); #if defined(__linux__) || defined(_ALLBSD_SOURCE) -#ifdef __linux__ - if (isOldKernel) { - int t = 1; - setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (char*) &t, sizeof(int)); - } else { -#endif /* __linux__ */ memset(&addr, 0, sizeof(addr)); #ifdef AF_INET6 if (ipv6_available()) { @@ -369,14 +312,10 @@ JVM_Connect(fd, (struct sockaddr *)&addr, len); #ifdef __linux__ - // After disconnecting a UDP socket, Linux kernel will set - // local port to zero if the port number comes from implicit - // bind. Successive send/recv on the same socket will fail. - // So bind again with former port number here. int localPort = 0; - if (JVM_GetSockName(fd, (struct sockaddr *)&addr, &len) == -1) { + if (JVM_GetSockName(fd, (struct sockaddr *)&addr, &len) == -1) return; - } + localPort = NET_GetPortFromSockaddr((struct sockaddr *)&addr); if (localPort == 0) { localPort = (*env)->GetIntField(env, this, pdsi_localPortID); @@ -388,9 +327,10 @@ { ((struct sockaddr_in*)&addr)->sin_port = htons(localPort); } + NET_Bind(fd, (struct sockaddr *)&addr, len); } - } + #endif #else JVM_Connect(fd, 0, 0); @@ -448,11 +388,7 @@ packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID); packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID); -#ifdef __linux__ - if (connected && !isOldKernel) { -#else if (connected) { -#endif /* arg to NET_Sendto () null in this case */ len = 0; rmtaddrP = 0; @@ -466,14 +402,14 @@ if (packetBufferLen > MAX_BUFFER_LEN) { /* When JNI-ifying the JDK's IO routines, we turned - * read's and write's of byte arrays of size greater + * reads and writes of byte arrays of size greater * than 2048 bytes into several operations of size 2048. * This saves a malloc()/memcpy()/free() for big * buffers. This is OK for file IO and TCP, but that * strategy violates the semantics of a datagram protocol. * (one big send) != (several smaller sends). So here - * we *must* alloc the buffer. Note it needn't be bigger - * than 65,536 (0xFFFF) the max size of an IP packet. + * we *must* allocate the buffer. Note it needn't be bigger + * than 65,536 (0xFFFF), the max size of an IP packet. * Anything bigger should be truncated anyway. * * We may want to use a smarter allocation scheme at some @@ -621,7 +557,7 @@ #else family = AF_INET; #endif - if (family == AF_INET) { /* this api can't handle IPV6 addresses */ + if (family == AF_INET) { /* this API can't handle IPV6 addresses */ int address = (*env)->GetIntField(env, iaObj, ia_addressID); (*env)->SetIntField(env, addressObj, ia_addressID, address); } @@ -695,14 +631,14 @@ if (packetBufferLen > MAX_BUFFER_LEN) { /* When JNI-ifying the JDK's IO routines, we turned - * read's and write's of byte arrays of size greater + * reads and writes of byte arrays of size greater * than 2048 bytes into several operations of size 2048. * This saves a malloc()/memcpy()/free() for big * buffers. This is OK for file IO and TCP, but that * strategy violates the semantics of a datagram protocol. * (one big send) != (several smaller sends). So here - * we *must* alloc the buffer. Note it needn't be bigger - * than 65,536 (0xFFFF) the max size of an IP packet. + * we *must* allocate the buffer. Note it needn't be bigger + * than 65,536 (0xFFFF), the max size of an IP packet. * anything bigger is truncated anyway. * * We may want to use a smarter allocation scheme at some @@ -855,14 +791,14 @@ if (packetBufferLen > MAX_BUFFER_LEN) { /* When JNI-ifying the JDK's IO routines, we turned - * read's and write's of byte arrays of size greater + * reads and writes of byte arrays of size greater * than 2048 bytes into several operations of size 2048. * This saves a malloc()/memcpy()/free() for big * buffers. This is OK for file IO and TCP, but that * strategy violates the semantics of a datagram protocol. * (one big send) != (several smaller sends). So here - * we *must* alloc the buffer. Note it needn't be bigger - * than 65,536 (0xFFFF) the max size of an IP packet. + * we *must* allocate the buffer. Note it needn't be bigger + * than 65,536 (0xFFFF) the max size of an IP packet, * anything bigger is truncated anyway. * * We may want to use a smarter allocation scheme at some @@ -883,24 +819,6 @@ fullPacket = &(BUF[0]); } -#ifdef __linux__ - /* - * On Linux with the 2.2 kernel we simulate connected datagrams by - * discarding packets - */ - if (isOldKernel) { - connected = (*env)->GetBooleanField(env, this, pdsi_connected); - if (connected) { - connectedAddress = (*env)->GetObjectField(env, this, pdsi_connectedAddress); - connectedPort = (*env)->GetIntField(env, this, pdsi_connectedPort); - - if (timeout) { - prevTime = JVM_CurrentTimeMillis(env, 0); - } - } - } -#endif - do { retry = JNI_FALSE; @@ -933,14 +851,6 @@ } } - /* - * Security Note: For Linux 2.2 with connected datagrams ensure that - * you receive into the stack/heap allocated buffer - do not attempt - * to receive directly into DatagramPacket's byte array. - * (ie: if the virtual machine support pinning don't use - * GetByteArrayElements or a JNI critical section and receive - * directly into the byte array) - */ len = SOCKADDR_LEN; n = NET_RecvFrom(fd, fullPacket, packetBufferLen, 0, (struct sockaddr *)&remote_addr, &len); @@ -971,47 +881,6 @@ jobject packetAddress; /* - * If we are connected then we know that the datagram that we have - * received is from the address that we are connected too. However - * on Linux with 2.2 kernel we have to simulate this behaviour by - * discarding any datagrams that aren't from the connected address. - */ -#ifdef __linux__ - if (isOldKernel && connected) { - - if (NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr) != connectedPort || - !NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, connectedAddress)) { - - /* - * Discard the datagram as it's not from the connected - * address - */ - retry = JNI_TRUE; - - /* - * Adjust timeout if necessary to ensure that we adhere to - * timeout semantics. - */ - if (timeout) { - jlong newTime = JVM_CurrentTimeMillis(env, 0); - timeout -= (newTime - prevTime); - if (timeout <= 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", - "Receive timed out"); - if (mallocedPacket) { - free(fullPacket); - } - return; - } - prevTime = newTime; - } - - continue; - } - } -#endif - - /* * success - fill in received address... * * REMIND: Fill in an int on the packet, and create inetadd @@ -1112,27 +981,16 @@ setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int)); -#ifdef __linux__ - if (isOldKernel) { - setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (char*) &t, sizeof(int)); - } - -#ifdef AF_INET6 +#if defined (__linux__) && defined (AF_INET6) /* * On Linux for IPv6 sockets we must set the hop limit - * to 1 to be compatible with default ttl of 1 for IPv4 sockets. + * to 1 to be compatible with default TTL of 1 for IPv4 sockets. */ if (domain == AF_INET6) { int ttl = 1; setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl, sizeof(ttl)); - - if (isOldKernel) { - (*env)->SetIntField(env, this, pdsi_ttlID, ttl); - } } -#endif - #endif /* __linux__ */ (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd); @@ -1250,16 +1108,6 @@ return; } -#ifdef __linux__ - /* - * Linux 2.2 kernel doesn't support IPV6_MULTICAST_IF socket - * option so record index for later retrival. - */ - if (isOldKernel) { - (*env)->SetIntField(env, this, pdsi_multicastInterfaceID, - (jint)index); - } -#endif } #endif /* AF_INET6 */ @@ -1326,8 +1174,6 @@ * InetAddress is bound * Set outgoing multicast interface using * IPPROTO_IPV6/IPV6_MULTICAST_IF - * On Linux 2.2 record interface index as can't - * query the multicast interface. * * SockOptions.IF_MULTICAST_IF2 :- * value is a NetworkInterface @@ -1338,8 +1184,6 @@ * IPv6: Obtain NetworkInterface.index * Set outgoing multicast interface using * IPPROTO_IPV6/IPV6_MULTICAST_IF - * On Linux 2.2 record interface index as can't - * query the multicast interface. * */ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, @@ -1436,15 +1280,6 @@ return; } -#ifdef __linux__ - /* - * Can't query IPV6_MULTICAST_LOOP on Linux 2.2 kernel so - * store it in impl so that we can simulate getsockopt. - */ - if (isOldKernel) { - (*env)->SetBooleanField(env, this, pdsi_loopbackID, on); - } -#endif } #endif /* AF_INET6 */ @@ -1507,7 +1342,7 @@ } /* - * Setting the multicast interface handled seperately + * Setting the multicast interface handled separately */ if (opt == java_net_SocketOptions_IP_MULTICAST_IF || opt == java_net_SocketOptions_IP_MULTICAST_IF2) { @@ -1594,8 +1429,7 @@ * Create InetAddress * IP_MULTICAST_IF returns struct ip_mreqn on 2.2 * kernel but struct in_addr on 2.4 kernel - * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF or - * obtain from impl is Linux 2.2 kernel + * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF * If index == 0 return InetAddress representing * anyLocalAddress. * If index > 0 query NetworkInterface by index @@ -1641,14 +1475,6 @@ struct in_addr *inP = ∈ int len = sizeof(struct in_addr); -#ifdef __linux__ - struct ip_mreqn mreqn; - if (isOldKernel) { - inP = (struct in_addr *)&mreqn; - len = sizeof(struct ip_mreqn); - } -#endif - if (JVM_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)inP, &len) < 0) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", @@ -1672,12 +1498,7 @@ addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0); CHECK_NULL_RETURN(addr, NULL); -#ifdef __linux__ - (*env)->SetIntField(env, addr, inet4_addrID, - (isOldKernel ? ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr)) ); -#else (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr)); -#endif /* * For IP_MULTICAST_IF return InetAddress @@ -1746,22 +1567,11 @@ jobject addr; jobject ni; -#ifdef __linux__ - /* - * Linux 2.2 kernel doesn't support IPV6_MULTICAST_IF socke option - * so use cached index. - */ - if (isOldKernel) { - index = (*env)->GetIntField(env, this, pdsi_multicastInterfaceID); - } else -#endif - { - if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, - (char*)&index, &len) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", - "Error getting socket option"); - return NULL; - } + if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (char*)&index, &len) < 0) { + NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + "Error getting socket option"); + return NULL; } if (ni_class == NULL) { @@ -1877,7 +1687,7 @@ } /* - * Handle IP_MULTICAST_IF seperately + * Handle IP_MULTICAST_IF separately */ if (opt == java_net_SocketOptions_IP_MULTICAST_IF || opt == java_net_SocketOptions_IP_MULTICAST_IF2) { @@ -1916,18 +1726,6 @@ return NULL; } - /* - * IP_MULTICAST_LOOP socket option isn't available on Linux 2.2 - * kernel with IPv6 so return value stored in impl. - */ -#if defined(AF_INET6) && defined(__linux__) - if (isOldKernel && opt == java_net_SocketOptions_IP_MULTICAST_LOOP && - level == IPPROTO_IPV6) { - int mode = (int)(*env)->GetBooleanField(env, this, pdsi_loopbackID); - return createBoolean(env, mode); - } -#endif - if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP && level == IPPROTO_IP) { optlen = sizeof(optval.c); @@ -1961,7 +1759,7 @@ } - /* should never rearch here */ + /* should never reach here */ return NULL; } @@ -2025,15 +1823,12 @@ } else { fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); } - /* setsockopt to be correct ttl */ + /* setsockopt to be correct TTL */ #ifdef AF_INET6 #ifdef __linux__ setTTL(env, fd, ttl); if (ipv6_available()) { setHopLimit(env, fd, ttl); - if (isOldKernel) { - (*env)->SetIntField(env, this, pdsi_ttlID, ttl); - } } #else /* __linux__ not defined */ if (ipv6_available()) { @@ -2076,21 +1871,12 @@ } else { fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); } - /* getsockopt of ttl */ + /* getsockopt of TTL */ #ifdef AF_INET6 if (ipv6_available()) { int ttl = 0; int len = sizeof(ttl); -#ifdef __linux__ - /* - * Linux 2.2 kernel doesn't support IPV6_MULTICAST_HOPS socket option - */ - if (isOldKernel) { - return (*env)->GetIntField(env, this, pdsi_ttlID); - } -#endif - if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char*)&ttl, &len) < 0) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", @@ -2258,14 +2044,10 @@ int index; int len = sizeof(index); - if (isOldKernel) { - index = (*env)->GetIntField(env, this, pdsi_multicastInterfaceID); - } else { - if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, - (char*)&index, &len) < 0) { - NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed"); - return; - } + if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (char*)&index, &len) < 0) { + NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed"); + return; } mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID)); @@ -2279,21 +2061,13 @@ struct in_addr *inP = ∈ socklen_t len = sizeof(struct in_addr); -#ifdef __linux__ - struct ip_mreqn mreqn; - if (isOldKernel) { - inP = (struct in_addr *)&mreqn; - len = sizeof(struct ip_mreqn); - } -#endif if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char *)inP, &len) < 0) { NET_ThrowCurrent(env, "getsockopt IP_MULTICAST_IF failed"); return; } #ifdef __linux__ - mname.imr_address.s_addr = - (isOldKernel ? mreqn.imr_address.s_addr : in.s_addr); + mname.imr_address.s_addr = in.s_addr; #else mname.imr_interface.s_addr = in.s_addr; @@ -2314,10 +2088,10 @@ * If IP_ADD_MEMBERSHIP returns ENOPROTOOPT on Linux and we've got * IPv6 enabled then it's possible that the kernel has been fixed * so we switch to IPV6_ADD_MEMBERSHIP socket option. - * As of 2.4.7 kernel IPV6_ADD_MEMERSHIP can't handle IPv4-mapped - * addresses so we have to use IP_ADD_MEMERSHIP for IPv4 multicast + * As of 2.4.7 kernel IPV6_ADD_MEMBERSHIP can't handle IPv4-mapped + * addresses so we have to use IP_ADD_MEMBERSHIP for IPv4 multicast * groups. However if the socket is an IPv6 socket then then setsockopt - * should reurn ENOPROTOOPT. We assume this will be fixed in Linux + * should return ENOPROTOOPT. We assume this will be fixed in Linux * at some stage. */ #if defined(__linux__) && defined(AF_INET6) @@ -2385,20 +2159,10 @@ int index; int len = sizeof(index); -#ifdef __linux__ - /* - * 2.2 kernel doens't support IPV6_MULTICAST_IF socket option - */ - if (isOldKernel) { - index = (*env)->GetIntField(env, this, pdsi_multicastInterfaceID); - } else -#endif - { - if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, - (char*)&index, &len) < 0) { - NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed"); - return; - } + if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (char*)&index, &len) < 0) { + NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed"); + return; } #ifdef __linux__ @@ -2408,7 +2172,7 @@ * subsequent leave groups to fail as there is no match. Thus we * pick the interface if there is a matching route. */ - if (index == 0 && !isOldKernel) { + if (index == 0) { int rt_index = getDefaultIPv6Interface(&(mname6.ipv6mr_multiaddr)); if (rt_index > 0) { index = rt_index;
--- a/src/solaris/native/java/net/PlainSocketImpl.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/PlainSocketImpl.c Thu Oct 11 16:59:50 2012 -0700 @@ -128,7 +128,7 @@ /* * The initroto function is called whenever PlainSocketImpl is - * loaded, to cache fieldIds for efficiency. This is called everytime + * loaded, to cache field IDs for efficiency. This is called every time * the Java class is loaded. * * Class: java_net_PlainSocketImpl @@ -589,7 +589,7 @@ /* set the address */ (*env)->SetObjectField(env, this, psi_addressID, iaObj); - /* intialize the local port */ + /* initialize the local port */ if (localport == 0) { /* Now that we're a connected socket, let's extract the port number * that the system chose for us and store it in the Socket object. @@ -909,7 +909,7 @@ } /* - * SO_TIMEOUT is a no-op on Solaris/Linux + * SO_TIMEOUT is a NOOP on Solaris/Linux */ if (cmd == java_net_SocketOptions_SO_TIMEOUT) { return;
--- a/src/solaris/native/java/net/SocketInputStream.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/SocketInputStream.c Thu Oct 11 16:59:50 2012 -0700 @@ -67,14 +67,14 @@ jint fd, nread; if (IS_NULL(fdObj)) { - /* should't this be a NullPointerException? -br */ + /* shouldn't this be a NullPointerException? -br */ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); return -1; } else { fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); /* Bug 4086704 - If the Socket associated with this file descriptor - * was closed (sysCloseFD), the the file descriptor is set to -1. + * was closed (sysCloseFD), then the file descriptor is set to -1. */ if (fd == -1) { JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
--- a/src/solaris/native/java/net/bsd_close.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/bsd_close.c Thu Oct 11 16:59:50 2012 -0700 @@ -68,7 +68,7 @@ /* * This limit applies if getlimit() returns unlimited. - * Unfortunately, this means if someone wants a higher limt + * Unfortunately, this means if someone wants a higher limit * then they have to set an explicit limit, higher than this, * which is probably counter-intuitive. */
--- a/src/solaris/native/java/net/net_util_md.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/net_util_md.c Thu Oct 11 16:59:50 2012 -0700 @@ -169,7 +169,7 @@ * for Solaris versions that do not support the ioctl() in getParam(). * Ugly, but only called once (for each sotype). * - * As an optimisation, we make a guess using the default values for Solaris + * As an optimization, we make a guess using the default values for Solaris * assuming they haven't been modified with ndd. */ @@ -217,23 +217,7 @@ #endif #ifdef __linux__ -static int kernelV22 = 0; static int vinit = 0; - -int kernelIsV22 () { - if (!vinit) { - struct utsname sysinfo; - if (uname(&sysinfo) == 0) { - sysinfo.release[3] = '\0'; - if (strcmp(sysinfo.release, "2.2") == 0) { - kernelV22 = JNI_TRUE; - } - } - vinit = 1; - } - return kernelV22; -} - static int kernelV24 = 0; static int vinit24 = 0; @@ -253,17 +237,11 @@ int getScopeID (struct sockaddr *him) { struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him; - if (kernelIsV22()) { - return 0; - } return hext->sin6_scope_id; } int cmpScopeID (unsigned int scope, struct sockaddr *him) { struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him; - if (kernelIsV22()) { - return 1; /* scope is ignored for comparison in 2.2 kernel */ - } return hext->sin6_scope_id == scope; } @@ -843,15 +821,14 @@ * address needs to be routed via the loopback interface. In this case, * we override the specified value with that of the loopback interface. * If no cached value exists and no value was specified by user, then - * we try to determine a value ffrom the routing table. In all these + * we try to determine a value from the routing table. In all these * cases the used value is cached for further use. */ #ifdef __linux__ if (IN6_IS_ADDR_LINKLOCAL(&(him6->sin6_addr))) { int cached_scope_id = 0, scope_id = 0; - int old_kernel = kernelIsV22(); - if (ia6_cachedscopeidID && !old_kernel) { + if (ia6_cachedscopeidID) { cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID); /* if cached value exists then use it. Otherwise, check * if scope is set in the address. @@ -891,13 +868,11 @@ * of sockaddr_in6. */ - if (!old_kernel) { - struct sockaddr_in6 *him6 = - (struct sockaddr_in6 *)him; - him6->sin6_scope_id = cached_scope_id != 0 ? - cached_scope_id : scope_id; - *len = sizeof(struct sockaddr_in6); - } + struct sockaddr_in6 *him6 = + (struct sockaddr_in6 *)him; + him6->sin6_scope_id = cached_scope_id != 0 ? + cached_scope_id : scope_id; + *len = sizeof(struct sockaddr_in6); } #else /* handle scope_id for solaris */ @@ -1208,7 +1183,7 @@ /* * Wrapper for getsockopt system routine - does any necessary - * pre/post processing to deal with OS specific oddies :- + * pre/post processing to deal with OS specific oddities :- * * IP_TOS is a no-op with IPv6 sockets as it's setup when * the connection is established. @@ -1287,7 +1262,7 @@ * * For IP_TOS socket option need to mask off bits as this * aren't automatically masked by the kernel and results in - * an error. In addition IP_TOS is a noop with IPv6 as it + * an error. In addition IP_TOS is a NOOP with IPv6 as it * should be setup as connection time. */ int @@ -1321,7 +1296,7 @@ /* * IPPROTO/IP_TOS :- - * 1. IPv6 on Solaris/Mac OS: no-op and will be set + * 1. IPv6 on Solaris/Mac OS: NOOP and will be set * in flowinfo field when connecting TCP socket, * or sending UDP packet. * 2. IPv6 on Linux: By default Linux ignores flowinfo
--- a/src/solaris/native/java/net/net_util_md.h Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/java/net/net_util_md.h Thu Oct 11 16:59:50 2012 -0700 @@ -144,7 +144,6 @@ * Utilities */ #ifdef __linux__ -extern int kernelIsV22(); extern int kernelIsV24(); #endif
--- a/src/solaris/native/sun/awt/initIDs.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/sun/awt/initIDs.c Thu Oct 11 16:59:50 2012 -0700 @@ -89,6 +89,12 @@ } JNIEXPORT void JNICALL +Java_java_awt_Choice_initIDs + (JNIEnv *env, jclass clazz) +{ +} + +JNIEXPORT void JNICALL Java_java_awt_Dimension_initIDs (JNIEnv *env, jclass clazz) {
--- a/src/solaris/native/sun/nio/ch/Net.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/solaris/native/sun/nio/ch/Net.c Thu Oct 11 16:59:50 2012 -0700 @@ -38,6 +38,7 @@ #include "net_util_md.h" #include "nio_util.h" #include "nio.h" +#include "sun_nio_ch_PollArrayWrapper.h" #ifdef _ALLBSD_SOURCE @@ -627,6 +628,26 @@ handleSocketError(env, errno); } +JNIEXPORT jint JNICALL +Java_sun_nio_ch_Net_poll(JNIEnv* env, jclass this, jobject fdo, jint events, jlong timeout) +{ + struct pollfd pfd; + int rv; + pfd.fd = fdval(env, fdo); + pfd.events = events; + rv = poll(&pfd, 1, timeout); + + if (rv >= 0) { + return pfd.revents; + } else if (errno == EINTR) { + return IOS_INTERRUPTED; + } else if (rv < 0) { + handleSocketError(env, errno); + return IOS_THROWN; + } +} + + /* Declared in nio_util.h */ jint
--- a/src/windows/native/sun/nio/ch/Net.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/nio/ch/Net.c Thu Oct 11 16:59:50 2012 -0700 @@ -35,6 +35,7 @@ #include "net_util.h" #include "sun_nio_ch_Net.h" +#include "sun_nio_ch_PollArrayWrapper.h" /** * Definitions to allow for building with older SDK include files. @@ -524,3 +525,49 @@ NET_ThrowNew(env, WSAGetLastError(), "shutdown"); } } + +JNIEXPORT jint JNICALL +Java_sun_nio_ch_Net_poll(JNIEnv* env, jclass this, jobject fdo, jint events, jlong timeout) +{ + int rv; + int revents = 0; + struct timeval t; + int lastError = 0; + fd_set rd, wr, ex; + jint fd = fdval(env, fdo); + + t.tv_sec = timeout / 1000; + t.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + if (events & sun_nio_ch_PollArrayWrapper_POLLIN) { + FD_SET(fd, &rd); + } + if (events & sun_nio_ch_PollArrayWrapper_POLLOUT || + events & sun_nio_ch_PollArrayWrapper_POLLCONN) { + FD_SET(fd, &wr); + } + FD_SET(fd, &ex); + + rv = select(fd+1, &rd, &wr, &ex, &t); + + /* save last winsock error */ + if (rv == SOCKET_ERROR) { + handleSocketError(env, lastError); + return IOS_THROWN; + } else if (rv >= 0) { + rv = 0; + if (FD_ISSET(fd, &rd)) { + rv |= sun_nio_ch_PollArrayWrapper_POLLIN; + } + if (FD_ISSET(fd, &wr)) { + rv |= sun_nio_ch_PollArrayWrapper_POLLOUT; + } + if (FD_ISSET(fd, &ex)) { + rv |= sun_nio_ch_PollArrayWrapper_POLLERR; + } + } + return rv; +}
--- a/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Thu Oct 11 16:59:50 2012 -0700 @@ -209,31 +209,26 @@ */ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePattern (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) { - WCHAR datePattern[BUFLEN]; - WCHAR timePattern[BUFLEN]; + WCHAR pattern[BUFLEN]; const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); - datePattern[0] = L'\0'; - timePattern[0] = L'\0'; + pattern[0] = L'\0'; if (dateStyle == 0 || dateStyle == 1) { - getLocaleInfoWrapper(langtag, LOCALE_SLONGDATE, datePattern, BUFLEN); + getLocaleInfoWrapper(langtag, LOCALE_SLONGDATE, pattern, BUFLEN); } else if (dateStyle == 2 || dateStyle == 3) { - getLocaleInfoWrapper(langtag, LOCALE_SSHORTDATE, datePattern, BUFLEN); + getLocaleInfoWrapper(langtag, LOCALE_SSHORTDATE, pattern, BUFLEN); } if (timeStyle == 0 || timeStyle == 1) { - getLocaleInfoWrapper(langtag, LOCALE_STIMEFORMAT, timePattern, BUFLEN); + getLocaleInfoWrapper(langtag, LOCALE_STIMEFORMAT, pattern, BUFLEN); } else if (timeStyle == 2 || timeStyle == 3) { - getLocaleInfoWrapper(langtag, LOCALE_SSHORTTIME, timePattern, BUFLEN); + getLocaleInfoWrapper(langtag, LOCALE_SSHORTTIME, pattern, BUFLEN); } - wcscat(datePattern, L" "); - wcscat(datePattern, timePattern); - (*env)->ReleaseStringChars(env, jlangtag, langtag); - return (*env)->NewString(env, datePattern, wcslen(datePattern)); + return (*env)->NewString(env, pattern, wcslen(pattern)); } /*
--- a/src/windows/native/sun/windows/awt_Choice.cpp Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/windows/awt_Choice.cpp Thu Oct 11 16:59:50 2012 -0700 @@ -79,6 +79,10 @@ static const UINT MINIMUM_NUMBER_OF_VISIBLE_ITEMS = 8; +namespace { + jfieldID selectedIndexID; +} + /************************************************************************* * AwtChoice class methods */ @@ -86,7 +90,6 @@ AwtChoice::AwtChoice() { m_hList = NULL; m_listDefWindowProc = NULL; - m_selectedItem = -1; } LPCTSTR AwtChoice::GetClassName() { @@ -102,7 +105,6 @@ AwtChoice* AwtChoice::Create(jobject peer, jobject parent) { - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject target = NULL; @@ -438,10 +440,14 @@ MsgRouting AwtChoice::WmNotify(UINT notifyCode) { if (notifyCode == CBN_SELCHANGE) { - int selectedItem = (int)SendMessage(CB_GETCURSEL); - if (selectedItem != CB_ERR && m_selectedItem != selectedItem){ - m_selectedItem = selectedItem; - DoCallback("handleAction", "(I)V", selectedItem); + int selectedIndex = (int)SendMessage(CB_GETCURSEL); + + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + jobject target = GetTarget(env); + int previousIndex = env->GetIntField(target, selectedIndexID); + + if (selectedIndex != CB_ERR && selectedIndex != previousIndex){ + DoCallback("handleAction", "(I)V", selectedIndex); } } else if (notifyCode == CBN_DROPDOWN) { @@ -695,6 +701,15 @@ extern "C" { +JNIEXPORT void JNICALL +Java_java_awt_Choice_initIDs(JNIEnv *env, jclass cls) +{ + TRY; + selectedIndexID = env->GetFieldID(cls, "selectedIndex", "I"); + DASSERT(selectedIndexID); + CATCH_BAD_ALLOC; +} + /* * Class: sun_awt_windows_WChoicePeer * Method: select
--- a/src/windows/native/sun/windows/awt_Choice.h Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/windows/awt_Choice.h Thu Oct 11 16:59:50 2012 -0700 @@ -94,7 +94,6 @@ static BOOL sm_isMouseMoveInList; HWND m_hList; WNDPROC m_listDefWindowProc; - int m_selectedItem; static LRESULT CALLBACK ListWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); };
--- a/src/windows/native/sun/windows/awt_Component.cpp Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/windows/awt_Component.cpp Thu Oct 11 16:59:50 2012 -0700 @@ -3144,7 +3144,8 @@ return; } -UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers) +UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey) + { // Handle the few cases where we need to take the modifier into // consideration for the Java VK code or where we have to take the keyboard @@ -3171,6 +3172,15 @@ break; }; + // check dead key + if (isDeadKey) { + for (int i = 0; charToDeadVKTable[i].c != 0; i++) { + if (charToDeadVKTable[i].c == character) { + return charToDeadVKTable[i].javaKey; + } + } + } + // for the general case, use a bi-directional table for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { if (keyMapTable[i].windowsKey == windowsKey) { @@ -3384,14 +3394,18 @@ } } -UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops) +UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey) { static Hashtable transTable("VKEY translations"); + static Hashtable deadKeyFlagTable("Dead Key Flags"); + isDeadKey = FALSE; // Try to translate using last saved translation if (ops == LOAD) { + void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); if (value != NULL) { + isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag)); return static_cast<UINT>(reinterpret_cast<INT_PTR>(value)); } } @@ -3484,12 +3498,13 @@ // instead of creating our own conversion tables, I'll let Win32 // convert the character for me. - WORD mbChar; + WORD wChar[2]; UINT scancode = ::MapVirtualKey(wkey, 0); - int converted = ::ToAsciiEx(wkey, scancode, keyboardState, - &mbChar, 0, GetKeyboardLayout()); + int converted = ::ToUnicodeEx(wkey, scancode, keyboardState, + wChar, 2, 0, GetKeyboardLayout()); UINT translation; + BOOL deadKeyFlag = (converted == 2); // Dead Key if (converted < 0) { @@ -3508,16 +3523,16 @@ } else // the caller expects a Unicode character. if (converted > 0) { - WCHAR unicodeChar[2]; - VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED, - (LPCSTR)&mbChar, 1, unicodeChar, 1)); - - translation = unicodeChar[0]; + translation = wChar[0]; } if (ops == SAVE) { transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), reinterpret_cast<void*>(static_cast<INT_PTR>(translation))); - } + deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), + reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag))); + } + + isDeadKey = deadKeyFlag; return translation; } @@ -3537,8 +3552,9 @@ UINT modifiers = GetJavaModifiers(); jint keyLocation = GetKeyLocation(wkey, flags); - UINT jkey = WindowsKeyToJavaKey(wkey, modifiers); - UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); + BOOL isDeadKey = FALSE; + UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey); + UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); @@ -3579,8 +3595,9 @@ UINT modifiers = GetJavaModifiers(); jint keyLocation = GetKeyLocation(wkey, flags); - UINT jkey = WindowsKeyToJavaKey(wkey, modifiers); - UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD); + BOOL isDeadKey = FALSE; + UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey); + UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED, @@ -5628,7 +5645,8 @@ } } - modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE); + BOOL isDeadKey = FALSE; + modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey); bCharChanged = (keyChar != modifiedChar); } break; @@ -7166,4 +7184,4 @@ removedDCs = removedDCs->next; delete tmpDCList; } -} +} \ No newline at end of file
--- a/src/windows/native/sun/windows/awt_Component.h Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/windows/awt_Component.h Thu Oct 11 16:59:50 2012 -0700 @@ -441,7 +441,7 @@ static jint GetJavaModifiers(); static jint GetButton(int mouseButton); static UINT GetButtonMK(int mouseButton); - static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers); + static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey); static void JavaKeyToWindowsKey(UINT javaKey, UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey); static void UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers); @@ -453,7 +453,7 @@ enum TransOps {NONE, LOAD, SAVE}; - UINT WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops); + UINT WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey); /* routines used for input method support */ void SetInputMethod(jobject im, BOOL useNativeCompWindow);
--- a/src/windows/native/sun/windows/awt_InputMethod.cpp Thu Oct 11 09:50:14 2012 -0700 +++ b/src/windows/native/sun/windows/awt_InputMethod.cpp Thu Oct 11 16:59:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, 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 @@ -517,10 +517,10 @@ jstring infojStr = NULL; if ((buffSize = ::ImmGetDescription(hkl, szImmDescription, 0)) > 0) { - szImmDescription = (LPTSTR) safe_Malloc(buffSize * sizeof(TCHAR)); + szImmDescription = (LPTSTR) safe_Malloc((buffSize+1) * sizeof(TCHAR)); if (szImmDescription != NULL) { - ImmGetDescription(hkl, szImmDescription, buffSize); + ImmGetDescription(hkl, szImmDescription, (buffSize+1)); infojStr = JNU_NewStringPlatform(env, szImmDescription);
--- a/test/ProblemList.txt Thu Oct 11 09:50:14 2012 -0700 +++ b/test/ProblemList.txt Thu Oct 11 16:59:50 2012 -0700 @@ -153,9 +153,6 @@ # 7144846 javax/management/remote/mandatory/connection/ReconnectTest.java generic-all -# 7158614, locks up Windows machines at least -sun/management/jmxremote/startstop/JMXStartStopTest.sh windows-all - # 7120365 javax/management/remote/mandatory/notif/DiffHBTest.java generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Choice/ItemStateChangeTest/ItemStateChangeTest.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, 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 7171412 + @summary awt Choice doesn't fire ItemStateChange when selecting item after select() call + @author Oleg Pekhovskiy: area=awt-choice + @library ../../regtesthelpers + @build Util + @run main ItemStateChangeTest +*/ + +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; +import java.awt.event.*; +import sun.awt.OSInfo; + +public class ItemStateChangeTest extends Frame { + + int events = 0; + + public static void main(String args[]) { + new ItemStateChangeTest(); + } + + public ItemStateChangeTest() { + + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + return; + } + + try { + + final Robot robot = new Robot(); + robot.setAutoDelay(20); + Util.waitForIdle(robot); + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + final Choice choice = new Choice(); + choice.add("A"); + choice.add("B"); + choice.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + ++events; + } + }); + + add(choice); + setSize(200, 150); + setVisible(true); + toFront(); + + // choose B + int y = chooseB(choice, robot, 16); + + // reset to A + choice.select(0); + robot.delay(20); + Util.waitForIdle(robot); + + // choose B again + chooseB(choice, robot, y); + + if (events == 2) { + System.out.println("Test passed!"); + } + else { + throw new RuntimeException("Test failed!"); + } + + } + catch (AWTException e) { + throw new RuntimeException("Test failed!"); + } + } + + final int chooseB(Choice choice, Robot robot, int y) { + while (true) { + // show drop-down list + Util.clickOnComp(choice, robot); + Util.waitForIdle(robot); + Point pt = choice.getLocationOnScreen(); + Dimension size = choice.getSize(); + // try to click B item + robot.mouseMove(pt.x + size.width / 2, pt.y + size.height + y); + Util.waitForIdle(robot); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + Util.waitForIdle(robot); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + Util.waitForIdle(robot); + if (choice.getSelectedIndex() == 1) { + break; + } + // if it's not B, position cursor lower by 2 pixels and try again + y += 2; + } + return y; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/List/EmptyListEventTest/EmptyListEventTest.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2008, 2012, 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 6366126 + * @summary List throws ArrayIndexOutOfBoundsException when pressing ENTER after removing all the items, Win32 + * @author Dmitry Cherepanov area=awt.list + * @run main EmptyListEventTest + */ +import java.awt.*; +import java.awt.event.*; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import sun.awt.SunToolkit; + +public class EmptyListEventTest { + + private static List list; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + // press mouse -> ItemEvent + Point point = getClickPoint(); + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + list.requestFocusInWindow(); + } + }); + + toolkit.realSync(); + + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != list) { + throw new RuntimeException("Test failed - list isn't focus owner."); + } + + // press key ENTER -> ActionEvent + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + toolkit.realSync(); + + // press key SPACE -> ItemEvent + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + toolkit.realSync(); + + // mouse double click -> ActionEvent + robot.setAutoDelay(10); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + } + + private static Point getClickPoint() throws Exception { + final Point[] result = new Point[1]; + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + Point point = list.getLocationOnScreen(); + point.translate(list.getWidth() / 2, list.getHeight() / 2); + result[0] = point; + + } + }); + + return result[0]; + + + } + + private static void createAndShowGUI() { + JFrame frame = new JFrame(); + frame.setSize(200, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JPanel panel = new JPanel(new BorderLayout()); + + frame.getToolkit().addAWTEventListener(new AWTEventListener() { + + public void eventDispatched(AWTEvent e) { + System.out.println(e); + } + }, AWTEvent.FOCUS_EVENT_MASK | AWTEvent.WINDOW_FOCUS_EVENT_MASK); + + + MyListener listener = new MyListener(); + + list = new List(4, true); + list.addActionListener(listener); + list.addItemListener(listener); + + panel.add(list); + + frame.getContentPane().add(panel); + frame.setVisible(true); + + } + + static class MyListener implements ActionListener, ItemListener { + + public void actionPerformed(ActionEvent ae) { + System.err.println(ae); + throw new RuntimeException("Test failed - list is empty so event is redundant"); + } + + public void itemStateChanged(ItemEvent ie) { + System.err.println(ie); + throw new RuntimeException("Test failed - list is empty so event is redundant"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/ScrollPane/ScrollPanePreferredSize/ScrollPanePreferredSize.java Thu Oct 11 16:59:50 2012 -0700 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, 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