Mercurial > hg > openjdk > lambda > jdk
changeset 9534:23e68a8e4b91
Merge
author | lana |
---|---|
date | Wed, 07 Aug 2013 19:56:20 -0700 |
parents | e193c4ad940a (current diff) 8c50c27418d3 (diff) |
children | e0f6039c0290 |
files | test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh |
diffstat | 182 files changed, 5608 insertions(+), 2731 deletions(-) [+] |
line wrap: on
line diff
--- a/src/macosx/native/java/util/SCDynamicStoreConfig.m Wed Aug 07 19:52:47 2013 -0700 +++ b/src/macosx/native/java/util/SCDynamicStoreConfig.m Wed Aug 07 19:56:20 2013 -0700 @@ -103,7 +103,6 @@ CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]); if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) { - NSLog(@"Unexpected CFType for realm Info: %lu", CFGetTypeID(realmInfo)); return nil; } @@ -140,7 +139,6 @@ SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL); if (store == NULL) { - NSLog(@"Unable to load SCDynamicStore to install NotificationCallback"); return; } @@ -171,19 +169,11 @@ SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL); if (store == NULL) { - NSLog(@"Unable to load SCDynamicStore"); - return NULL; - } - - // Create the store if it is NULL and set it. - if (store == NULL) { - NSLog(@"Invalid value for SCDynamicStore"); return NULL; } CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS); if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) { - NSLog(@"Unable to load realm info from SCDynamicStore"); if (realms) CFRelease(realms); CFRelease(store); return NULL; @@ -192,7 +182,6 @@ CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS); if (realmMappings == NULL || CFGetTypeID(realmMappings) != CFArrayGetTypeID()) { - NSLog(@"Unable to load realm mapping info from SCDynamicStore"); if (realmMappings) CFRelease(realmMappings); CFRelease(realms); CFRelease(store);
--- a/src/share/classes/com/sun/security/auth/PolicyFile.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/com/sun/security/auth/PolicyFile.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,10 @@ import sun.security.util.PropertyExpander; +import sun.security.provider.PolicyParser.PrincipalEntry; +import sun.security.provider.PolicyParser.GrantEntry; +import sun.security.provider.PolicyParser.PermissionEntry; + /** * This class represents a default implementation for * <code>javax.security.auth.Policy</code>. @@ -469,7 +473,8 @@ * @param policyFile the policy Reader object. */ private void init(URL policy) { - PolicyParser pp = new PolicyParser(expandProperties); + sun.security.provider.PolicyParser pp = + new sun.security.provider.PolicyParser(expandProperties); try { InputStreamReader isr = new InputStreamReader(getInputStream(policy)); @@ -477,12 +482,12 @@ isr.close(); KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(), pp.getKeyStoreType()); - Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements(); + Enumeration<GrantEntry> enum_ = pp.grantElements(); while (enum_.hasMoreElements()) { - PolicyParser.GrantEntry ge = enum_.nextElement(); + GrantEntry ge = enum_.nextElement(); addGrantEntry(ge, keyStore); } - } catch (PolicyParser.ParsingException pe) { + } catch (sun.security.provider.PolicyParser.ParsingException pe) { System.err.println(AUTH_POLICY + rb.getString(".error.parsing.") + policy); System.err.println(AUTH_POLICY + @@ -521,8 +526,8 @@ * * @return null if signedBy alias is not recognized */ - CodeSource getCodeSource(PolicyParser.GrantEntry ge, KeyStore keyStore) - throws java.net.MalformedURLException + CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore) + throws java.net.MalformedURLException { Certificate[] certs = null; if (ge.signedBy != null) { @@ -559,20 +564,18 @@ /** * Add one policy entry to the vector. */ - private void addGrantEntry(PolicyParser.GrantEntry ge, - KeyStore keyStore) { + private void addGrantEntry(GrantEntry ge, KeyStore keyStore) { if (debug != null) { debug.println("Adding policy entry: "); debug.println(" signedBy " + ge.signedBy); debug.println(" codeBase " + ge.codeBase); if (ge.principals != null && ge.principals.size() > 0) { - ListIterator<PolicyParser.PrincipalEntry> li = - ge.principals.listIterator(); + ListIterator<PrincipalEntry> li = ge.principals.listIterator(); while (li.hasNext()) { - PolicyParser.PrincipalEntry pppe = li.next(); - debug.println(" " + pppe.principalClass + - " " + pppe.principalName); + PrincipalEntry pppe = li.next(); + debug.println(" " + pppe.getPrincipalClass() + + " " + pppe.getPrincipalName()); } } debug.println(); @@ -584,10 +587,9 @@ if (codesource == null) return; PolicyEntry entry = new PolicyEntry(codesource); - Enumeration<PolicyParser.PermissionEntry> enum_ = - ge.permissionElements(); + Enumeration<PermissionEntry> enum_ = ge.permissionElements(); while (enum_.hasMoreElements()) { - PolicyParser.PermissionEntry pe = enum_.nextElement(); + PermissionEntry pe = enum_.nextElement(); try { // XXX special case PrivateCredentialPermission-SELF Permission perm; @@ -998,11 +1000,11 @@ return true; } - ListIterator<PolicyParser.PrincipalEntry> pli = - scs.getPrincipals().listIterator(); + ListIterator<PrincipalEntry> pli = + scs.getPrincipals().listIterator(); while (pli.hasNext()) { - PolicyParser.PrincipalEntry principal = pli.next(); + PrincipalEntry principal = pli.next(); // XXX // if the Policy entry's Principal does not contain a @@ -1050,30 +1052,29 @@ * if (y == 1), it's the principal name. */ private String[][] getPrincipalInfo - (PolicyParser.PrincipalEntry principal, - final CodeSource accCs) { + (PrincipalEntry principal, final CodeSource accCs) { // there are 3 possibilities: // 1) the entry's Principal class and name are not wildcarded // 2) the entry's Principal name is wildcarded only // 3) the entry's Principal class and name are wildcarded - if (!principal.principalClass.equals - (PolicyParser.PrincipalEntry.WILDCARD_CLASS) && - !principal.principalName.equals - (PolicyParser.PrincipalEntry.WILDCARD_NAME)) { + if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + !principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { // build a PrivateCredentialPermission for the principal // from the Policy entry String[][] info = new String[1][2]; - info[0][0] = principal.principalClass; - info[0][1] = principal.principalName; + info[0][0] = principal.getPrincipalClass(); + info[0][1] = principal.getPrincipalName(); return info; - } else if (!principal.principalClass.equals - (PolicyParser.PrincipalEntry.WILDCARD_CLASS) && - principal.principalName.equals - (PolicyParser.PrincipalEntry.WILDCARD_NAME)) { + } else if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { // build a PrivateCredentialPermission for all // the Subject's principals that are instances of principalClass @@ -1088,7 +1089,7 @@ // If it doesn't, we should stop here with a ClassCastException. @SuppressWarnings("unchecked") Class<? extends Principal> pClass = (Class<? extends Principal>) - Class.forName(principal.principalClass, false, + Class.forName(principal.getPrincipalClass(), false, ClassLoader.getSystemClassLoader()); principalSet = scs.getSubject().getPrincipals(pClass); } catch (Exception e) { @@ -1387,6 +1388,7 @@ } } +@SuppressWarnings("deprecation") class PolicyPermissions extends PermissionCollection { private static final long serialVersionUID = -1954188373270545523L;
--- a/src/share/classes/com/sun/security/auth/SubjectCodeSource.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/com/sun/security/auth/SubjectCodeSource.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -33,6 +33,7 @@ import java.lang.reflect.Constructor; import javax.security.auth.Subject; +import sun.security.provider.PolicyParser.PrincipalEntry; /** * <p> This <code>SubjectCodeSource</code> class contains @@ -57,7 +58,7 @@ }); private Subject subject; - private LinkedList<PolicyParser.PrincipalEntry> principals; + private LinkedList<PrincipalEntry> principals; private static final Class[] PARAMS = { String.class }; private static final sun.security.util.Debug debug = sun.security.util.Debug.getInstance("auth", "\t[Auth Access]"); @@ -87,14 +88,14 @@ * <code>SubjectCodeSource</code> <p> */ SubjectCodeSource(Subject subject, - LinkedList<PolicyParser.PrincipalEntry> principals, + LinkedList<PrincipalEntry> principals, URL url, Certificate[] certs) { super(url, certs); this.subject = subject; this.principals = (principals == null ? - new LinkedList<PolicyParser.PrincipalEntry>() : - new LinkedList<PolicyParser.PrincipalEntry>(principals)); + new LinkedList<PrincipalEntry>() : + new LinkedList<PrincipalEntry>(principals)); sysClassLoader = java.security.AccessController.doPrivileged (new java.security.PrivilegedAction<ClassLoader>() { public ClassLoader run() { @@ -114,7 +115,7 @@ * <code>SubjectCodeSource</code> as a <code>LinkedList</code> * of <code>PolicyParser.PrincipalEntry</code> objects. */ - LinkedList<PolicyParser.PrincipalEntry> getPrincipals() { + LinkedList<PrincipalEntry> getPrincipals() { return principals; } @@ -167,7 +168,7 @@ */ public boolean implies(CodeSource codesource) { - LinkedList<PolicyParser.PrincipalEntry> subjectList = null; + LinkedList<PrincipalEntry> subjectList = null; if (codesource == null || !(codesource instanceof SubjectCodeSource) || @@ -197,20 +198,19 @@ return false; } - ListIterator<PolicyParser.PrincipalEntry> li = - this.principals.listIterator(0); + ListIterator<PrincipalEntry> li = this.principals.listIterator(0); while (li.hasNext()) { - PolicyParser.PrincipalEntry pppe = li.next(); + PrincipalEntry pppe = li.next(); try { // handle PrincipalComparators Class<?> principalComparator = Class.forName( - pppe.principalClass, true, sysClassLoader); + pppe.getPrincipalClass(), true, sysClassLoader); Constructor<?> c = principalComparator.getConstructor(PARAMS); PrincipalComparator pc = (PrincipalComparator)c.newInstance - (new Object[] { pppe.principalName }); + (new Object[] { pppe.getPrincipalName() }); if (!pc.implies(that.getSubject())) { if (debug != null) @@ -236,11 +236,10 @@ Iterator<Principal> i = that.getSubject().getPrincipals().iterator(); - subjectList = new LinkedList<PolicyParser.PrincipalEntry>(); + subjectList = new LinkedList<PrincipalEntry>(); while (i.hasNext()) { Principal p = i.next(); - PolicyParser.PrincipalEntry spppe = - new PolicyParser.PrincipalEntry + PrincipalEntry spppe = new PrincipalEntry (p.getClass().getName(), p.getName()); subjectList.add(spppe); } @@ -281,23 +280,19 @@ * <i>pppe</i> argument. */ private boolean subjectListImpliesPrincipalEntry( - LinkedList<PolicyParser.PrincipalEntry> subjectList, - PolicyParser.PrincipalEntry pppe) { + LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) { - ListIterator<PolicyParser.PrincipalEntry> li = - subjectList.listIterator(0); + ListIterator<PrincipalEntry> li = subjectList.listIterator(0); while (li.hasNext()) { - PolicyParser.PrincipalEntry listPppe = li.next(); + PrincipalEntry listPppe = li.next(); - if (pppe.principalClass.equals - (PolicyParser.PrincipalEntry.WILDCARD_CLASS) || - pppe.principalClass.equals - (listPppe.principalClass)) { - - if (pppe.principalName.equals - (PolicyParser.PrincipalEntry.WILDCARD_NAME) || - pppe.principalName.equals - (listPppe.principalName)) + if (pppe.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) || + pppe.getPrincipalClass().equals(listPppe.getPrincipalClass())) + { + if (pppe.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME) || + pppe.getPrincipalName().equals(listPppe.getPrincipalName())) return true; } } @@ -390,13 +385,12 @@ } } if (principals != null) { - ListIterator<PolicyParser.PrincipalEntry> li = - principals.listIterator(); + ListIterator<PrincipalEntry> li = principals.listIterator(); while (li.hasNext()) { - PolicyParser.PrincipalEntry pppe = li.next(); + PrincipalEntry pppe = li.next(); returnMe = returnMe + rb.getString("NEWLINE") + - pppe.principalClass + " " + - pppe.principalName; + pppe.getPrincipalClass() + " " + + pppe.getPrincipalName(); } } return returnMe;
--- a/src/share/classes/com/sun/tools/hat/resources/hat.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/com/sun/tools/hat/resources/hat.js Wed Aug 07 19:56:20 2013 -0700 @@ -151,7 +151,7 @@ while (tmp != null) { res[res.length] = tmp; tmp = tmp.superclass; - } + } return res; } @@ -263,16 +263,19 @@ if (name == 'class') { return wrapJavaValue(instance.clazz); - } else if (name == 'toString') { - return function() { - return instance.toString(); - } } else if (name == 'wrapped-object') { return instance; } return undefined; - } + }, + __call__: function(name) { + if (name == 'toString') { + return instance.toString(); + } else { + return undefined; + } + } } } @@ -297,7 +300,7 @@ return true; } } - return theJavaClassProto[name] != undefined; + return false; }, __get__ : function(name) { for (var i in fields) { @@ -305,7 +308,7 @@ return wrapJavaValue(fields[i].value); } } - return theJavaClassProto[name]; + return undefined; } } @@ -322,7 +325,12 @@ this.name = jclass.name; this.fields = jclass.fields; this['wrapped-object'] = jclass; - this.__proto__ = this.statics; + } + + for (var i in theJavaClassProto) { + if (typeof theJavaClassProto[i] == 'function') { + JavaClassWrapper.prototype[i] = theJavaClassProto[i]; + } } // returns wrapper for Java object arrays @@ -334,32 +342,35 @@ __getIds__ : function() { var res = new Array(elements.length); for (var i = 0; i < elements.length; i++) { - res[i] = i; + res[i] = String(i); } return res; }, __has__: function(name) { - return (typeof(name) == 'number' && - name >= 0 && name < elements.length) || + return (name >= 0 && name < elements.length) || name == 'length' || name == 'class' || name == 'toString' || name == 'wrapped-object'; }, __get__ : function(name) { - if (typeof(name) == 'number' && - name >= 0 && name < elements.length) { + if (name >= 0 && name < elements.length) { return wrapJavaValue(elements[name]); } else if (name == 'length') { return elements.length; } else if (name == 'class') { return wrapJavaValue(array.clazz); - } else if (name == 'toString') { - return function() { return array.toString(); } } else if (name == 'wrapped-object') { return array; } else { return undefined; } - } + }, + __call__: function(name) { + if (name == 'toString') { + return array.toString(); + } else { + return undefined; + } + } } } @@ -373,26 +384,22 @@ __getIds__ : function() { var r = new Array(array.length); for (var i = 0; i < array.length; i++) { - r[i] = i; + r[i] = String(i); } return r; }, __has__: function(name) { - return (typeof(name) == 'number' && - name >= 0 && name < array.length) || + return (name >= 0 && name < array.length) || name == 'length' || name == 'class' || name == 'toString' || name == 'wrapped-object'; }, __get__: function(name) { - if (typeof(name) == 'number' && - name >= 0 && name < array.length) { + if (name >= 0 && name < array.length) { return elements[name]; } if (name == 'length') { return array.length; - } else if (name == 'toString') { - return function() { return array.valueString(true); } } else if (name == 'wrapped-object') { return array; } else if (name == 'class') { @@ -400,7 +407,14 @@ } else { return undefined; } - } + }, + __call__: function(name) { + if (name == 'toString') { + return array.valueString(true); + } else { + return undefined; + } + } } } return javaObject(thing); @@ -673,34 +687,33 @@ __getIds__ : function() { var res = new Array(path.length); for (var i = 0; i < path.length; i++) { - res[i] = i; + res[i] = String(i); } return res; }, __has__ : function (name) { - return (typeof(name) == 'number' && - name >= 0 && name < path.length) || + return (name >= 0 && name < path.length) || name == 'length' || name == 'toHtml' || name == 'toString'; }, __get__ : function(name) { - if (typeof(name) == 'number' && - name >= 0 && name < path.length) { + if (name >= 0 && name < path.length) { return path[name]; } else if (name == 'length') { return path.length; - } else if (name == 'toHtml') { - return function() { - return computeDescription(true); - } - } else if (name == 'toString') { - return function() { - return computeDescription(false); - } } else { return undefined; } }, + __call__: function(name) { + if (name == 'toHtml') { + return computeDescription(true); + } else if (name == 'toString') { + return computeDescription(false); + } else { + return undefined; + } + } }; } @@ -1005,22 +1018,8 @@ return "<a href='/object/" + id + "'>" + name + "@" + id + "</a>"; } - } else if ((typeof(obj) == 'object') || (obj instanceof JSAdapter)) { - if (obj instanceof java.lang.Object) { - // script wrapped Java object - obj = wrapIterator(obj); - // special case for enumeration - if (obj instanceof java.util.Enumeration) { - var res = "[ "; - while (obj.hasMoreElements()) { - res += toHtml(obj.nextElement()) + ", "; - } - res += "]"; - return res; - } else { - return obj; - } - } else if (obj instanceof Array) { + } else if (obj instanceof Object) { + if (Array.isArray(obj)) { // script array var res = "[ "; for (var i in obj) { @@ -1047,8 +1046,19 @@ } } } else { - // JavaScript primitive value - return obj; + // a Java object + obj = wrapIterator(obj); + // special case for enumeration + if (obj instanceof java.util.Enumeration) { + var res = "[ "; + while (obj.hasMoreElements()) { + res += toHtml(obj.nextElement()) + ", "; + } + res += "]"; + return res; + } else { + return obj; + } } }
--- a/src/share/classes/com/sun/tools/hat/resources/oqlhelp.html Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/com/sun/tools/hat/resources/oqlhelp.html Wed Aug 07 19:56:20 2013 -0700 @@ -79,7 +79,7 @@ <li>select all Strings of length 100 or more <pre> <code> - select s from java.lang.String s where s.count >= 100 + select s from java.lang.String s where s.value.length >= 100 </code> </pre> <li>select all int arrays of length 256 or more @@ -92,7 +92,7 @@ <pre> <code> select s.value.toString() from java.lang.String s - where /java/(s.value.toString()) + where /java/.test(s.value.toString()) </code> </pre> <li>show path value of all File objects @@ -219,7 +219,6 @@ <pre> <code> select heap.findClass("java.lang.System").statics.props - select heap.findClass("java.lang.System").props </code> </pre> <li>get number of fields of java.lang.String class @@ -237,7 +236,7 @@ <li>select all classes that have name pattern java.net.* <pre> <code> - select <a href="#filter">filter</a>(heap.classes(), "/java.net./(it.name)") + select <a href="#filter">filter</a>(heap.classes(), "/java.net./.test(it.name)") </code> </pre> </ul> @@ -536,7 +535,7 @@ Example: print number of classes that have specific name pattern <pre> <code> - select count(<a href="#classes">heap.classes()</a>, "/java.io./(it.name)") + select count(<a href="#classes">heap.classes()</a>, "/java.io./.test(it.name)") </code> </pre> @@ -559,14 +558,14 @@ <li>show all classes that have java.io.* name pattern <pre> <code> - select filter(<a href="#classes">heap.classes</a>(), "/java.io./(it.name)") + select filter(<a href="#classes">heap.classes</a>(), "/java.io./.test(it.name)") </code> </pre> <li> show all referrers of URL object where the referrer is not from java.net package <pre> <code> - select filter(<a href="#referrers">referrers</a>(u), "! /java.net./(<a href="#classof">classof</a>(it).name)") + select filter(<a href="#referrers">referrers</a>(u), "! /java.net./.test(<a href="#classof">classof</a>(it).name)") from java.net.URL u </code> </pre> @@ -619,13 +618,13 @@ <li>find the maximum length of any String instance <pre> <code> - select max(map(heap.objects('java.lang.String', false), 'it.count')) + select max(map(heap.objects('java.lang.String', false), 'it.value.length')) </code> </pre> <li>find string instance that has the maximum length <pre> <code> - select max(heap.objects('java.lang.String'), 'lhs.count > rhs.count') + select max(heap.objects('java.lang.String'), 'lhs.value.length > rhs.value.length') </code> </pre> </ul> @@ -775,7 +774,7 @@ <pre> <code> - select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').props.table, 'it != null'), + select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').statics.props.table, 'it != null'), function (it) { var res = ""; while (it != null) {
--- a/src/share/classes/java/applet/AppletContext.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/applet/AppletContext.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ /** * Returns an <code>Image</code> object that can then be painted on - * the screen. The <code>url</code> argument<code> </code>that is + * the screen. The <code>url</code> argument that is * passed as an argument must specify an absolute URL. * <p> * This method always returns immediately, whether or not the image @@ -157,7 +157,7 @@ * @param stream stream to be associated with the specified key. If this * parameter is <code>null</code>, the specified key is removed * in this applet context. - * @throws <code>IOException</code> if the stream size exceeds a certain + * @throws IOException if the stream size exceeds a certain * size limit. Size limit is decided by the implementor of this * interface. * @since 1.4
--- a/src/share/classes/java/beans/AppletInitializer.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/AppletInitializer.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -68,7 +68,6 @@ * the Applet with its Container during the subsequent invocation of its * addChildren() method. * </ol> - * </p> * * @param newAppletBean The newly instantiated JavaBean * @param bCtxt The BeanContext intended for this Applet, or
--- a/src/share/classes/java/beans/Beans.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/Beans.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ * <p> * Instantiate a JavaBean. * </p> - * + * @return a JavaBean * @param cls the class-loader from which we should create * the bean. If this is null, then the system * class-loader is used. @@ -82,6 +82,7 @@ * <p> * Instantiate a JavaBean. * </p> + * @return a JavaBean * * @param cls the class-loader from which we should create * the bean. If this is null, then the system @@ -137,6 +138,7 @@ * the JDK appletviewer (for a reference browser environment) and the * BDK BeanBox (for a reference bean container). * + * @return a JavaBean * @param cls the class-loader from which we should create * the bean. If this is null, then the system * class-loader is used. @@ -361,6 +363,8 @@ * This method is provided in Beans 1.0 as a hook to allow the * addition of more flexible bean behaviour in the future. * + * @return an object representing a specified type view of the + * source object * @param bean Object from which we want to obtain a view. * @param targetType The type of view we'd like to get. * @@ -384,7 +388,6 @@ return Introspector.isSubclass(bean.getClass(), targetType); } - /** * Test if we are in design-mode. *
--- a/src/share/classes/java/beans/ConstructorProperties.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/ConstructorProperties.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, 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 @@ -61,7 +61,7 @@ the {@code getY()} method. Since parameter names are not in general available at runtime, without the annotation there would be no way to know whether the parameters correspond to {@code getX()} - and {@code getY()} or the other way around.</p> + and {@code getY()} or the other way around. @since 1.6 */
--- a/src/share/classes/java/beans/DefaultPersistenceDelegate.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/DefaultPersistenceDelegate.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -382,6 +382,7 @@ * a class such that no property value depends on the value of * a subsequent property. * + * @param type the type of the instances * @param oldInstance The instance to be copied. * @param newInstance The instance that is to be modified. * @param out The stream to which any initialization statements should be written.
--- a/src/share/classes/java/beans/EventHandler.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/EventHandler.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -515,6 +515,7 @@ *</pre> *</blockquote> * + * @param <T> the type to create * @param listenerInterface the listener interface to create a proxy for * @param target the object that will perform the action * @param action the name of a (possibly qualified) property or method on @@ -570,6 +571,7 @@ *</pre> *</blockquote> * + * @param <T> the type to create * @param listenerInterface the listener interface to create a proxy for * @param target the object that will perform the action * @param action the name of a (possibly qualified) property or method on @@ -659,6 +661,7 @@ * </pre> *</blockquote> * + * @param <T> the type to create * @param listenerInterface the listener interface to create a proxy for * @param target the object that will perform the action * @param action the name of a (possibly qualified) property or method on
--- a/src/share/classes/java/beans/Expression.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/Expression.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -139,7 +139,7 @@ * replaces this default value in the same way that any other value * would, ensuring that expressions are never evaluated more than once. * <p> - * See the <code>excecute</code> method for details on how + * See the <code>execute</code> method for details on how * methods are chosen using the dynamic types of the target * and arguments. * @@ -147,6 +147,8 @@ * @see #setValue * * @return The result of applying this method to these arguments. + * @throws Exception if the method with the specified methodName + * throws an exception */ public Object getValue() throws Exception { if (value == unbound) {
--- a/src/share/classes/java/beans/IndexedPropertyDescriptor.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/IndexedPropertyDescriptor.java Wed Aug 07 19:56:20 2013 -0700 @@ -207,6 +207,8 @@ * Sets the method that should be used to read an indexed property value. * * @param readMethod The new indexed read method. + * @throws IntrospectionException if an exception occurs during + * introspection. */ public synchronized void setIndexedReadMethod(Method readMethod) throws IntrospectionException { @@ -285,6 +287,8 @@ * Sets the method that should be used to write an indexed property value. * * @param writeMethod The new indexed write method. + * @throws IntrospectionException if an exception occurs during + * introspection. */ public synchronized void setIndexedWriteMethod(Method writeMethod) throws IntrospectionException {
--- a/src/share/classes/java/beans/Introspector.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/Introspector.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -93,8 +93,17 @@ public class Introspector { // Flags that can be used to control getBeanInfo: + /** + * Flag to indicate to use of all beaninfo. + */ public final static int USE_ALL_BEANINFO = 1; + /** + * Flag to indicate to ignore immediate beaninfo. + */ public final static int IGNORE_IMMEDIATE_BEANINFO = 2; + /** + * Flag to indicate to ignore all beaninfo. + */ public final static int IGNORE_ALL_BEANINFO = 3; // Static Caches to speed up introspection. @@ -202,7 +211,7 @@ * If the BeanInfo class for a Java Bean has been previously Introspected * based on the same arguments, then the BeanInfo class is retrieved * from the BeanInfo cache. - * + * @return the BeanInfo for the bean * @param beanClass The bean class to be analyzed. * @param stopClass The baseclass at which to stop the analysis. Any * methods/properties/events in the stopClass or in its baseclasses
--- a/src/share/classes/java/beans/PersistenceDelegate.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/PersistenceDelegate.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -197,6 +197,7 @@ * The default implementation, calls the <code>initialize</code> * method of the type's superclass. * + * @param type the type of the instances * @param oldInstance The instance to be copied. * @param newInstance The instance that is to be modified. * @param out The stream to which any initialization statements should be written.
--- a/src/share/classes/java/beans/PropertyChangeSupport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/PropertyChangeSupport.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -156,7 +156,7 @@ * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine * the parameter. * - * <pre> + * <pre>{@code * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners(); * for (int i = 0; i < listeners.length; i++) { * if (listeners[i] instanceof PropertyChangeListenerProxy) { @@ -168,7 +168,7 @@ * } * } * } - *</pre> + * }</pre> * * @see PropertyChangeListenerProxy * @return all of the <code>PropertyChangeListeners</code> added or an
--- a/src/share/classes/java/beans/PropertyDescriptor.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/PropertyDescriptor.java Wed Aug 07 19:56:20 2013 -0700 @@ -243,6 +243,7 @@ * Sets the method that should be used to read the property value. * * @param readMethod The new read method. + * @throws IntrospectionException if the read method is invalid */ public synchronized void setReadMethod(Method readMethod) throws IntrospectionException { @@ -313,6 +314,7 @@ * Sets the method that should be used to write the property value. * * @param writeMethod The new write method. + * @throws IntrospectionException if the write method is invalid */ public synchronized void setWriteMethod(Method writeMethod) throws IntrospectionException {
--- a/src/share/classes/java/beans/Transient.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/Transient.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, 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 @@ -40,7 +40,7 @@ * A {@code true} value for the "transient" attribute * indicates to encoders derived from {@link Encoder} * that this feature should be ignored. - * <p/> + * <p> * The {@code Transient} annotation may be be used * in any of the methods that are involved * in a {@link FeatureDescriptor} subclass @@ -49,7 +49,7 @@ * to put the annotation and it is this declaration * that takes precedence in the case of multiple annotations * being defined for the same feature. - * <p/> + * <p> * To declare a feature non-transient in a class * whose superclass declares it transient, * use {@code @Transient(false)}. @@ -64,5 +64,11 @@ @Target({METHOD}) @Retention(RUNTIME) public @interface Transient { + /** + * Returns whether or not the {@code Introspector} should + * construct artifacts for the annotated method. + * @return whether or not the {@code Introspector} should + * construct artifacts for the annotated method + */ boolean value() default true; }
--- a/src/share/classes/java/beans/VetoableChangeSupport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/VetoableChangeSupport.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ * <p> * Here is an example of {@code VetoableChangeSupport} usage that follows * the rules and recommendations laid out in the JavaBeans™ specification: - * <pre> + * <pre>{@code * public class MyBean { * private final VetoableChangeSupport vcs = new VetoableChangeSupport(this); * @@ -68,7 +68,7 @@ * * [...] * } - * </pre> + * }</pre> * <p> * A {@code VetoableChangeSupport} instance is thread-safe. * <p> @@ -156,7 +156,7 @@ * <code>VetoableChangeListenerProxy</code>, perform the cast, and examine * the parameter. * - * <pre> + * <pre>{@code * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners(); * for (int i = 0; i < listeners.length; i++) { * if (listeners[i] instanceof VetoableChangeListenerProxy) { @@ -168,7 +168,7 @@ * } * } * } - *</pre> + * }</pre> * * @see VetoableChangeListenerProxy * @return all of the <code>VetoableChangeListeners</code> added or an
--- a/src/share/classes/java/beans/beancontext/BeanContext.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContext.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -64,10 +64,12 @@ * and is defined by the * <code>java.beans.Beans.instantiate()</code> method. * + * @return a javaBean named as a child of this + * <code>BeanContext</code> * @param beanName The name of the JavaBean to instantiate * as a child of this <code>BeanContext</code> - * @throws <code>IOException</code> - * @throws <code>ClassNotFoundException</code> if the class identified + * @throws IOException if an IO problem occurs + * @throws ClassNotFoundException if the class identified * by the beanName parameter is not found */ Object instantiateChild(String beanName) throws IOException, ClassNotFoundException; @@ -83,7 +85,7 @@ * @return an <code>InputStream</code> for reading the resource, * or <code>null</code> if the resource could not * be found. - * @throws <code>IllegalArgumentException</code> if + * @throws IllegalArgumentException if * the resource is not valid */ InputStream getResourceAsStream(String name, BeanContextChild bcc) throws IllegalArgumentException; @@ -98,7 +100,7 @@ * @param bcc the specified child * @return a <code>URL</code> for the named * resource for the specified child - * @throws <code>IllegalArgumentException</code> + * @throws IllegalArgumentException * if the resource is not valid */ URL getResource(String name, BeanContextChild bcc) throws IllegalArgumentException; @@ -109,7 +111,7 @@ * this <code>BeanContext</code> whenever it adds * or removes a child <code>Component</code>(s). * - * @param bcml the <code>BeanContextMembershipListener</code> to be added + * @param bcml the BeanContextMembershipListener to be added */ void addBeanContextMembershipListener(BeanContextMembershipListener bcml);
--- a/src/share/classes/java/beans/beancontext/BeanContextChild.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContextChild.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -82,7 +82,7 @@ * </p> * @param bc The <code>BeanContext</code> with which * to associate this <code>BeanContextChild</code>. - * @throws <code>PropertyVetoException</code> if the + * @throws PropertyVetoException if the * addition of the specified <code>BeanContext</code> is refused. */ void setBeanContext(BeanContext bc) throws PropertyVetoException;
--- a/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java Wed Aug 07 19:56:20 2013 -0700 @@ -78,6 +78,7 @@ * construct a BeanContextChildSupport where the JavaBean component * itself implements BeanContextChild, and encapsulates this, delegating * that interface to this implementation + * @param bcc the underlying bean context child */ public BeanContextChildSupport(BeanContextChild bcc) { @@ -94,7 +95,7 @@ * this <code>BeanContextChildSupport</code>. * @param bc the new value to be assigned to the <code>BeanContext</code> * property - * @throws <code>PropertyVetoException</code> if the change is rejected + * @throws PropertyVetoException if the change is rejected */ public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException { if (bc == beanContext) return; @@ -361,6 +362,9 @@ */ protected VetoableChangeSupport vcSupport; + /** + * The bean context. + */ protected transient BeanContext beanContext; /**
--- a/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -103,6 +103,7 @@ * Is the child specified affected by the event? * @return <code>true</code> if affected, <code>false</code> * if not + * @param child the object to check for being affected */ public boolean contains(Object child) { return children.contains(child);
--- a/src/share/classes/java/beans/beancontext/BeanContextServices.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContextServices.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -60,6 +60,7 @@ * @param serviceClass the service to add * @param serviceProvider the <code>BeanContextServiceProvider</code> * associated with the service + * @return true if the service was successful added, false otherwise */ boolean addService(Class serviceClass, BeanContextServiceProvider serviceProvider); @@ -108,7 +109,7 @@ * @param bcsrl the * <code>BeanContextServiceRevokedListener</code> to notify * if the service should later become revoked - * @throws TooManyListenersException + * @throws TooManyListenersException if there are too many listeners * @return a reference to this context's named * Service as requested or <code>null</code> */
--- a/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -603,12 +603,16 @@ serviceProvider = bcsp; } + /** + * Returns the service provider. + * @return the service provider + */ protected BeanContextServiceProvider getServiceProvider() { return serviceProvider; } - /* - * fields + /** + * The service provider. */ protected BeanContextServiceProvider serviceProvider; @@ -618,6 +622,9 @@ * subclasses can override this method to create new subclasses of * BCSSServiceProvider without having to overrride addService() in * order to instantiate. + * @param sc the class + * @param bcsp the service provider + * @return a service provider without overriding addService() */ protected BCSSServiceProvider createBCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) { @@ -629,7 +636,7 @@ /** * add a BeanContextServicesListener * - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public void addBeanContextServicesListener(BeanContextServicesListener bcsl) { @@ -660,6 +667,8 @@ /** * add a service + * @param serviceClass the service class + * @param bcsp the service provider */ public boolean addService(Class serviceClass, BeanContextServiceProvider bcsp) { @@ -668,6 +677,10 @@ /** * add a service + * @param serviceClass the service class + * @param bcsp the service provider + * @param fireEvent whether or not an event should be fired + * @return true if the service was successfully added */ protected boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent) { @@ -709,6 +722,9 @@ /** * remove a service + * @param serviceClass the service class + * @param bcsp the service provider + * @param revokeCurrentServicesNow whether or not to revoke the service */ public void revokeService(Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow) { @@ -1067,6 +1083,7 @@ /** * Fires a <tt>BeanContextServiceEvent</tt> notifying of a new service. + * @param serviceClass the service class */ protected final void fireServiceAdded(Class serviceClass) { BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass); @@ -1109,6 +1126,8 @@ * Fires a <tt>BeanContextServiceRevokedEvent</tt> * indicating that a particular service is * no longer available. + * @param serviceClass the service class + * @param revokeNow whether or not the event should be revoked now */ protected final void fireServiceRevoked(Class serviceClass, boolean revokeNow) { Object[] copy;
--- a/src/share/classes/java/beans/beancontext/BeanContextSupport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/beans/beancontext/BeanContextSupport.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,6 @@ /** * This helper class provides a utility implementation of the * java.beans.beancontext.BeanContext interface. - * </p> * <p> * Since this class directly implements the BeanContext interface, the class * can, and is intended to be used either by subclassing this implementation, @@ -351,9 +350,8 @@ * of Child without having to override add() or the other Collection * methods that add children to the set. * </p> - * * @param targetChild the child to create the Child on behalf of - * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy + * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy * @return Subtype-specific subclass of Child without overriding collection methods */ protected BCSChild createBCSChild(Object targetChild, Object peer) { @@ -492,6 +490,7 @@ * @param callChildSetBC used to indicate that * the child should be notified that it is no * longer nested in this <tt>BeanContext</tt>. + * @return whether or not was present before being removed */ protected boolean remove(Object targetChild, boolean callChildSetBC) { @@ -580,7 +579,8 @@ /** * add Collection to set of Children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation + * @return this implementation unconditionally throws {@code UnsupportedOperationException} */ public boolean addAll(Collection c) { throw new UnsupportedOperationException(); @@ -589,7 +589,9 @@ /** * remove all specified children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation + * @return this implementation unconditionally throws {@code UnsupportedOperationException} + */ public boolean removeAll(Collection c) { throw new UnsupportedOperationException(); @@ -599,7 +601,8 @@ /** * retain only specified children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation + * @return this implementation unconditionally throws {@code UnsupportedOperationException} */ public boolean retainAll(Collection c) { throw new UnsupportedOperationException(); @@ -608,7 +611,7 @@ /** * clear the children (Unsupported) * implementations must synchronized on the hierarchy lock and "children" protected field - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException thrown unconditionally by this implementation */ public void clear() { throw new UnsupportedOperationException(); @@ -618,7 +621,7 @@ * Adds a BeanContextMembershipListener * * @param bcml the BeanContextMembershipListener to add - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) { @@ -636,7 +639,7 @@ * Removes a BeanContextMembershipListener * * @param bcml the BeanContextMembershipListener to remove - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) { @@ -655,7 +658,7 @@ * @param bcc the child object making the request. * * @return the requested resource as an InputStream - * @throws NullPointerException + * @throws NullPointerException if the argument is null */ public InputStream getResourceAsStream(String name, BeanContextChild bcc) { @@ -849,6 +852,8 @@ * * This method should not however be used by subclasses to replace their * own implementation (if any) of writeObject(). + * @param oos the {@code ObjectOutputStream} to use during serialization + * @throws IOException if serialization failed */ protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException { @@ -864,6 +869,9 @@ * * This method should not however be used by subclasses to replace their * own implementation (if any) of readObject(). + * @param ois the {@code ObjectInputStream} to use during deserialization + * @throws IOException if deserialization failed + * @throws ClassNotFoundException if needed classes are not found */ protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException { @@ -914,6 +922,8 @@ * used by readObject to deserialize a collection. * @param ois the ObjectInputStream to use * @param coll the Collection + * @throws IOException if deserialization failed + * @throws ClassNotFoundException if needed classes are not found */ protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException { int count = 0; @@ -1005,6 +1015,9 @@ * When an instance of this class is used as a delegate for the * implementation of the BeanContext protocols (and its subprotocols) * there exists a 'chicken and egg' problem during deserialization + * @param ois the ObjectInputStream to use + * @throws IOException if deserialization failed + * @throws ClassNotFoundException if needed classes are not found */ public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException { @@ -1122,6 +1135,7 @@ * immediately prior to their being added to the BeanContext. * </p> * + * @param targetChild the child to create the Child on behalf of * @return true iff the child may be added to this BeanContext, otherwise false. */ @@ -1136,6 +1150,7 @@ * immediately prior to their being removed from the BeanContext. * </p> * + * @param targetChild the child to create the Child on behalf of * @return true iff the child may be removed from this BeanContext, otherwise false. */ @@ -1147,6 +1162,8 @@ * subclasses may override this method to simply extend add() semantics * after the child has been added and before the event notification has * occurred. The method is called with the child synchronized. + * @param child the child + * @param bcsc the BCSChild */ protected void childJustAddedHook(Object child, BCSChild bcsc) { @@ -1156,6 +1173,8 @@ * subclasses may override this method to simply extend remove() semantics * after the child has been removed and before the event notification has * occurred. The method is called with the child synchronized. + * @param child the child + * @param bcsc the BCSChild */ protected void childJustRemovedHook(Object child, BCSChild bcsc) { @@ -1254,6 +1273,7 @@ /** * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface + * @param bcme the event to fire */ protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) { @@ -1267,6 +1287,7 @@ /** * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface + * @param bcme the event to fire */ protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) {
--- a/src/share/classes/java/net/SocketAddress.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/net/SocketAddress.java Wed Aug 07 19:56:20 2013 -0700 @@ -39,4 +39,7 @@ * @since 1.4 */ public abstract class SocketAddress implements java.io.Serializable { + + static final long serialVersionUID = 5215720748342549866L; + }
--- a/src/share/classes/java/nio/file/Files.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/nio/file/Files.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,10 +25,10 @@ package java.nio.file; -import java.nio.ByteBuffer; import java.nio.file.attribute.*; import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileTypeDetector; +import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; import java.io.Closeable; @@ -2965,7 +2965,63 @@ } /** - * Read all the bytes from a file. The method ensures that the file is + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + + /** + * Reads all the bytes from an input stream. Uses {@code initialSize} as a hint + * about how many bytes the stream will have. + * + * @param source + * the input stream to read from + * @param initialSize + * the initial size of the byte array to allocate + * + * @return a byte array containing the bytes read from the file + * + * @throws IOException + * if an I/O error occurs reading from the stream + * @throws OutOfMemoryError + * if an array of the required size cannot be allocated + */ + private static byte[] read(InputStream source, int initialSize) + throws IOException + { + int capacity = initialSize; + byte[] buf = new byte[capacity]; + int nread = 0; + int n; + for (;;) { + // read to EOF which may read more or less than initialSize (eg: file + // is truncated while we are reading) + while ((n = source.read(buf, nread, capacity - nread)) > 0) + nread += n; + + // if last call to source.read() returned -1, we are done + // otherwise, try to read one more byte; if that failed we're done too + if (n < 0 || (n = source.read()) < 0) + break; + + // one more byte was read; need to allocate a larger buffer + if (capacity <= MAX_BUFFER_SIZE - capacity) { + capacity = Math.max(capacity << 1, BUFFER_SIZE); + } else { + if (capacity == MAX_BUFFER_SIZE) + throw new OutOfMemoryError("Required array size too large"); + capacity = MAX_BUFFER_SIZE; + } + buf = Arrays.copyOf(buf, capacity); + buf[nread++] = (byte)n; + } + return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); + } + + /** + * Reads all the bytes from a file. The method ensures that the file is * closed when all bytes have been read or an I/O error, or other runtime * exception, is thrown. * @@ -2989,22 +3045,13 @@ * method is invoked to check read access to the file. */ public static byte[] readAllBytes(Path path) throws IOException { - try (FileChannel fc = FileChannel.open(path)) { + try (FileChannel fc = FileChannel.open(path); + InputStream is = Channels.newInputStream(fc)) { long size = fc.size(); - if (size > (long)Integer.MAX_VALUE) + if (size > (long)MAX_BUFFER_SIZE) throw new OutOfMemoryError("Required array size too large"); - byte[] arr = new byte[(int)size]; - ByteBuffer bb = ByteBuffer.wrap(arr); - while (bb.hasRemaining()) { - if (fc.read(bb) < 0) { - // truncated - break; - } - } - - int nread = bb.position(); - return (nread == size) ? arr : Arrays.copyOf(arr, nread); + return read(is, (int)size); } }
--- a/src/share/classes/java/rmi/server/RMISocketFactory.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/rmi/server/RMISocketFactory.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -33,15 +33,47 @@ * in order to obtain client and server sockets for RMI calls. An * application may use the <code>setSocketFactory</code> method to * request that the RMI runtime use its socket factory instance - * instead of the default implementation.<p> + * instead of the default implementation. * - * The default socket factory implementation used goes through a + * <p>The default socket factory implementation performs a * three-tiered approach to creating client sockets. First, a direct * socket connection to the remote VM is attempted. If that fails * (due to a firewall), the runtime uses HTTP with the explicit port * number of the server. If the firewall does not allow this type of * communication, then HTTP to a cgi-bin script on the server is used - * to POST the RMI call.<p> + * to POST the RMI call. + * + * <p>The default socket factory implementation creates server sockets that + * are bound to the wildcard address, which accepts requests from all network + * interfaces. + * + * @implNote + * <p>You can use the {@code RMISocketFactory} class to create a server socket that + * is bound to a specific address, restricting the origin of requests. For example, + * the following code implements a socket factory that binds server sockets to the + * loopback address. This restricts RMI to processing requests only from the local host. + * + * <pre>{@code + * class LoopbackSocketFactory extends RMISocketFactory { + * public ServerSocket createServerSocket(int port) throws IOException { + * return new ServerSocket(port, 5, InetAddress.getLoopbackAddress()); + * } + * + * public Socket createSocket(String host, int port) throws IOException { + * // just call the default client socket factory + * return RMISocketFactory.getDefaultSocketFactory() + * .createSocket(host, port); + * } + * } + * + * // ... + * + * RMISocketFactory.setSocketFactory(new LoopbackSocketFactory()); + * }</pre> + * + * Set the {@code java.rmi.server.hostname} system property + * to a host name (typically {@code localhost}) that resolves to the loopback + * interface to ensure that the generated stubs use the right network interface. * * @author Ann Wollrath * @author Peter Jones
--- a/src/share/classes/java/rmi/server/UnicastRemoteObject.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/rmi/server/UnicastRemoteObject.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -100,6 +100,26 @@ * </ul> * </ul> * + * <p>If an object is exported with the + * {@link #exportObject(Remote) exportObject(Remote)} + * or + * {@link #exportObject(Remote, int) exportObject(Remote, port)} + * methods, or if a subclass constructor invokes one of the + * {@link #UnicastRemoteObject()} + * or + * {@link #UnicastRemoteObject(int) UnicastRemoteObject(port)} + * constructors, the object is exported with a server socket created using the + * {@link RMISocketFactory} + * class. + * + * @implNote + * <p>By default, server sockets created by the {@link RMISocketFactory} class + * listen on all network interfaces. See the + * {@link RMISocketFactory} class and the section + * <a href="{@docRoot}/../platform/rmi/spec/rmi-server29.html">RMI Socket Factories</a> + * in the + * <a href="{@docRoot}/../platform/rmi/spec/rmiTOC.html">Java RMI Specification</a>. + * * @author Ann Wollrath * @author Peter Jones * @since JDK1.1
--- a/src/share/classes/java/security/Security.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/security/Security.java Wed Aug 07 19:56:20 2013 -0700 @@ -326,17 +326,13 @@ * * <p>A provider cannot be added if it is already installed. * - * <p>First, if there is a security manager, its - * {@code checkSecurityAccess} - * method is called with the string - * {@code "insertProvider."+provider.getName()} - * to see if it's ok to add a new provider. - * If the default implementation of {@code checkSecurityAccess} - * is used (i.e., that method is not overriden), then this will result in - * a call to the security manager's {@code checkPermission} method - * with a - * {@code SecurityPermission("insertProvider."+provider.getName())} - * permission. + * <p>If there is a security manager, the + * {@link java.lang.SecurityManager#checkSecurityAccess} method is called + * with the {@code "insertProvider"} permission target name to see if + * it's ok to add a new provider. If this permission check is denied, + * {@code checkSecurityAccess} is called again with the + * {@code "insertProvider."+provider.getName()} permission target name. If + * both checks are denied, a {@code SecurityException} is thrown. * * @param provider the provider to be added. * @@ -360,7 +356,7 @@ public static synchronized int insertProviderAt(Provider provider, int position) { String providerName = provider.getName(); - check("insertProvider." + providerName); + checkInsertProvider(providerName); ProviderList list = Providers.getFullProviderList(); ProviderList newList = ProviderList.insertAt(list, provider, position - 1); if (list == newList) { @@ -373,17 +369,13 @@ /** * Adds a provider to the next position available. * - * <p>First, if there is a security manager, its - * {@code checkSecurityAccess} - * method is called with the string - * {@code "insertProvider."+provider.getName()} - * to see if it's ok to add a new provider. - * If the default implementation of {@code checkSecurityAccess} - * is used (i.e., that method is not overriden), then this will result in - * a call to the security manager's {@code checkPermission} method - * with a - * {@code SecurityPermission("insertProvider."+provider.getName())} - * permission. + * <p>If there is a security manager, the + * {@link java.lang.SecurityManager#checkSecurityAccess} method is called + * with the {@code "insertProvider"} permission target name to see if + * it's ok to add a new provider. If this permission check is denied, + * {@code checkSecurityAccess} is called again with the + * {@code "insertProvider."+provider.getName()} permission target name. If + * both checks are denied, a {@code SecurityException} is thrown. * * @param provider the provider to be added. * @@ -863,6 +855,23 @@ } } + private static void checkInsertProvider(String name) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + try { + security.checkSecurityAccess("insertProvider"); + } catch (SecurityException se1) { + try { + security.checkSecurityAccess("insertProvider." + name); + } catch (SecurityException se2) { + // throw first exception, but add second to suppressed + se1.addSuppressed(se2); + throw se1; + } + } + } + } + /* * Returns all providers who satisfy the specified * criterion.
--- a/src/share/classes/java/security/SecurityPermission.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/security/SecurityPermission.java Wed Aug 07 19:56:20 2013 -0700 @@ -130,14 +130,17 @@ * </tr> * * <tr> - * <td>insertProvider.{provider name}</td> - * <td>Addition of a new provider, with the specified name</td> + * <td>insertProvider</td> + * <td>Addition of a new provider</td> * <td>This would allow somebody to introduce a possibly * malicious provider (e.g., one that discloses the private keys passed * to it) as the highest-priority provider. This would be possible * because the Security object (which manages the installed providers) * currently does not check the integrity or authenticity of a provider - * before attaching it.</td> + * before attaching it. The "insertProvider" permission subsumes the + * "insertProvider.{provider name}" permission (see the section below for + * more information). + * </td> * </tr> * * <tr> @@ -186,9 +189,10 @@ * </table> * * <P> - * The following permissions are associated with classes that have been - * deprecated: {@link Identity}, {@link IdentityScope}, {@link Signer}. Use of - * them is discouraged. See the applicable classes for more information. + * The following permissions have been superseded by newer permissions or are + * associated with classes that have been deprecated: {@link Identity}, + * {@link IdentityScope}, {@link Signer}. Use of them is discouraged. See the + * applicable classes for more information. * <P> * * <table border=1 cellpadding=5 summary="target name,what the permission allows, and associated risks"> @@ -199,6 +203,23 @@ * </tr> * * <tr> + * <td>insertProvider.{provider name}</td> + * <td>Addition of a new provider, with the specified name</td> + * <td>Use of this permission is discouraged from further use because it is + * possible to circumvent the name restrictions by overriding the + * {@link java.security.Provider#getName} method. Also, there is an equivalent + * level of risk associated with granting code permission to insert a provider + * with a specific name, or any name it chooses. Users should use the + * "insertProvider" permission instead. + * <p>This would allow somebody to introduce a possibly + * malicious provider (e.g., one that discloses the private keys passed + * to it) as the highest-priority provider. This would be possible + * because the Security object (which manages the installed providers) + * currently does not check the integrity or authenticity of a provider + * before attaching it.</td> + * </tr> + * + * <tr> * <td>setSystemScope</td> * <td>Setting of the system identity scope</td> * <td>This would allow an attacker to configure the system identity scope with @@ -306,7 +327,6 @@ * @throws NullPointerException if {@code name} is {@code null}. * @throws IllegalArgumentException if {@code name} is empty. */ - public SecurityPermission(String name) { super(name); @@ -323,7 +343,6 @@ * @throws NullPointerException if {@code name} is {@code null}. * @throws IllegalArgumentException if {@code name} is empty. */ - public SecurityPermission(String name, String actions) { super(name, actions);
--- a/src/share/classes/java/util/ArrayPrefixHelpers.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/ArrayPrefixHelpers.java Wed Aug 07 19:56:20 2013 -0700 @@ -128,6 +128,7 @@ this.lo = lo; this.hi = hi; } + @SuppressWarnings("unchecked") public final void compute() { final BinaryOperator<T> fn; final T[] a; @@ -692,6 +693,4 @@ } } } - - -} \ No newline at end of file +}
--- a/src/share/classes/java/util/Collections.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Collections.java Wed Aug 07 19:56:20 2013 -0700 @@ -1143,6 +1143,7 @@ public boolean removeIf(Predicate<? super E> filter) { throw new UnsupportedOperationException(); } + @SuppressWarnings("unchecked") @Override public Spliterator<E> spliterator() { return (Spliterator<E>)c.spliterator(); @@ -1900,7 +1901,7 @@ private static final long serialVersionUID = -2239321462712562324L; - EmptyNavigableMap() { super(new TreeMap()); } + EmptyNavigableMap() { super(new TreeMap<K,V>()); } @Override public NavigableSet<K> navigableKeySet() @@ -1928,46 +1929,52 @@ public K ceilingKey(K key) { return nm.ceilingKey(key); } public K higherKey(K key) { return nm.higherKey(key); } + @SuppressWarnings("unchecked") public Entry<K, V> lowerEntry(K key) { Entry<K,V> lower = (Entry<K, V>) nm.lowerEntry(key); return (null != lower) - ? new UnmodifiableEntrySet.UnmodifiableEntry(lower) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(lower) : null; } + @SuppressWarnings("unchecked") public Entry<K, V> floorEntry(K key) { Entry<K,V> floor = (Entry<K, V>) nm.floorEntry(key); return (null != floor) - ? new UnmodifiableEntrySet.UnmodifiableEntry(floor) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(floor) : null; } + @SuppressWarnings("unchecked") public Entry<K, V> ceilingEntry(K key) { Entry<K,V> ceiling = (Entry<K, V>) nm.ceilingEntry(key); return (null != ceiling) - ? new UnmodifiableEntrySet.UnmodifiableEntry(ceiling) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(ceiling) : null; } + @SuppressWarnings("unchecked") public Entry<K, V> higherEntry(K key) { Entry<K,V> higher = (Entry<K, V>) nm.higherEntry(key); return (null != higher) - ? new UnmodifiableEntrySet.UnmodifiableEntry(higher) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(higher) : null; } + @SuppressWarnings("unchecked") public Entry<K, V> firstEntry() { Entry<K,V> first = (Entry<K, V>) nm.firstEntry(); return (null != first) - ? new UnmodifiableEntrySet.UnmodifiableEntry(first) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(first) : null; } + @SuppressWarnings("unchecked") public Entry<K, V> lastEntry() { Entry<K,V> last = (Entry<K, V>) nm.lastEntry(); return (null != last) - ? new UnmodifiableEntrySet.UnmodifiableEntry(last) + ? new UnmodifiableEntrySet.UnmodifiableEntry<>(last) : null; } @@ -2360,7 +2367,7 @@ } public NavigableSet<E> tailSet(E fromElement) { synchronized (mutex) { - return new SynchronizedNavigableSet(ns.tailSet(fromElement, true), mutex); + return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, true), mutex); } } @@ -2925,7 +2932,7 @@ public NavigableMap<K, V> descendingMap() { synchronized (mutex) { return - new SynchronizedNavigableMap(nm.descendingMap(), mutex); + new SynchronizedNavigableMap<>(nm.descendingMap(), mutex); } } @@ -2935,13 +2942,13 @@ public NavigableSet<K> navigableKeySet() { synchronized (mutex) { - return new SynchronizedNavigableSet(nm.navigableKeySet(), mutex); + return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex); } } public NavigableSet<K> descendingKeySet() { synchronized (mutex) { - return new SynchronizedNavigableSet(nm.descendingKeySet(), mutex); + return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex); } } @@ -2959,27 +2966,27 @@ } public SortedMap<K,V> tailMap(K fromKey) { synchronized (mutex) { - return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex); + return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex); } } public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { synchronized (mutex) { - return new SynchronizedNavigableMap( + return new SynchronizedNavigableMap<>( nm.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } } public NavigableMap<K, V> headMap(K toKey, boolean inclusive) { synchronized (mutex) { - return new SynchronizedNavigableMap( + return new SynchronizedNavigableMap<>( nm.headMap(toKey, inclusive), mutex); } } public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) { synchronized (mutex) { - return new SynchronizedNavigableMap( + return new SynchronizedNavigableMap<>( nm.tailMap(fromKey, inclusive), mutex); } } @@ -4081,7 +4088,7 @@ public Entry<K, V> lowerEntry(K key) { Entry<K,V> lower = nm.lowerEntry(key); return (null != lower) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(lower, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(lower, valueType) : null; } @@ -4090,7 +4097,7 @@ public Entry<K, V> floorEntry(K key) { Entry<K,V> floor = nm.floorEntry(key); return (null != floor) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(floor, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(floor, valueType) : null; } @@ -4099,7 +4106,7 @@ public Entry<K, V> ceilingEntry(K key) { Entry<K,V> ceiling = nm.ceilingEntry(key); return (null != ceiling) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(ceiling, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(ceiling, valueType) : null; } @@ -4108,7 +4115,7 @@ public Entry<K, V> higherEntry(K key) { Entry<K,V> higher = nm.higherEntry(key); return (null != higher) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(higher, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(higher, valueType) : null; } @@ -4117,14 +4124,14 @@ public Entry<K, V> firstEntry() { Entry<K,V> first = nm.firstEntry(); return (null != first) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(first, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(first, valueType) : null; } public Entry<K, V> lastEntry() { Entry<K,V> last = nm.lastEntry(); return (null != last) - ? new CheckedMap.CheckedEntrySet.CheckedEntry(last, valueType) + ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(last, valueType) : null; } @@ -4132,14 +4139,14 @@ Entry<K,V> entry = nm.pollFirstEntry(); return (null == entry) ? null - : new CheckedMap.CheckedEntrySet.CheckedEntry(entry, valueType); + : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); } public Entry<K, V> pollLastEntry() { Entry<K,V> entry = nm.pollLastEntry(); return (null == entry) ? null - : new CheckedMap.CheckedEntrySet.CheckedEntry(entry, valueType); + : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); } public NavigableMap<K, V> descendingMap() {
--- a/src/share/classes/java/util/Comparator.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Comparator.java Wed Aug 07 19:56:20 2013 -0700 @@ -352,6 +352,7 @@ * @see Comparable * @since 1.8 */ + @SuppressWarnings("unchecked") public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE; } @@ -374,7 +375,7 @@ * @since 1.8 */ public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) { - return new Comparators.NullComparator(true, comparator); + return new Comparators.NullComparator<>(true, comparator); } /** @@ -395,7 +396,7 @@ * @since 1.8 */ public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) { - return new Comparators.NullComparator(false, comparator); + return new Comparators.NullComparator<>(false, comparator); } /**
--- a/src/share/classes/java/util/Comparators.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Comparators.java Wed Aug 07 19:56:20 2013 -0700 @@ -87,12 +87,12 @@ @Override public Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); - return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other)); + return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other)); } @Override public Comparator<T> reversed() { - return new NullComparator(!nullFirst, real == null ? null : real.reversed()); + return new NullComparator<>(!nullFirst, real == null ? null : real.reversed()); } } }
--- a/src/share/classes/java/util/Deque.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Deque.java Wed Aug 07 19:56:20 2013 -0700 @@ -38,7 +38,7 @@ /** * A linear collection that supports element insertion and removal at * both ends. The name <i>deque</i> is short for "double ended queue" - * and is usually pronounced "deck". Most <tt>Deque</tt> + * and is usually pronounced "deck". Most {@code Deque} * implementations place no fixed limits on the number of elements * they may contain, but this interface supports capacity-restricted * deques as well as those with no fixed size limit. @@ -47,10 +47,10 @@ * ends of the deque. Methods are provided to insert, remove, and * examine the element. Each of these methods exists in two forms: * one throws an exception if the operation fails, the other returns a - * special value (either <tt>null</tt> or <tt>false</tt>, depending on + * special value (either {@code null} or {@code false}, depending on * the operation). The latter form of the insert operation is * designed specifically for use with capacity-restricted - * <tt>Deque</tt> implementations; in most implementations, insert + * {@code Deque} implementations; in most implementations, insert * operations cannot fail. * * <p>The twelve methods described above are summarized in the @@ -58,6 +58,7 @@ * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Summary of Deque methods</caption> * <tr> * <td></td> * <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td> @@ -72,38 +73,39 @@ * </tr> * <tr> * <td><b>Insert</b></td> - * <td>{@link #addFirst addFirst(e)}</td> - * <td>{@link #offerFirst offerFirst(e)}</td> - * <td>{@link #addLast addLast(e)}</td> - * <td>{@link #offerLast offerLast(e)}</td> + * <td>{@link Deque#addFirst addFirst(e)}</td> + * <td>{@link Deque#offerFirst offerFirst(e)}</td> + * <td>{@link Deque#addLast addLast(e)}</td> + * <td>{@link Deque#offerLast offerLast(e)}</td> * </tr> * <tr> * <td><b>Remove</b></td> - * <td>{@link #removeFirst removeFirst()}</td> - * <td>{@link #pollFirst pollFirst()}</td> - * <td>{@link #removeLast removeLast()}</td> - * <td>{@link #pollLast pollLast()}</td> + * <td>{@link Deque#removeFirst removeFirst()}</td> + * <td>{@link Deque#pollFirst pollFirst()}</td> + * <td>{@link Deque#removeLast removeLast()}</td> + * <td>{@link Deque#pollLast pollLast()}</td> * </tr> * <tr> * <td><b>Examine</b></td> - * <td>{@link #getFirst getFirst()}</td> - * <td>{@link #peekFirst peekFirst()}</td> - * <td>{@link #getLast getLast()}</td> - * <td>{@link #peekLast peekLast()}</td> + * <td>{@link Deque#getFirst getFirst()}</td> + * <td>{@link Deque#peekFirst peekFirst()}</td> + * <td>{@link Deque#getLast getLast()}</td> + * <td>{@link Deque#peekLast peekLast()}</td> * </tr> * </table> * * <p>This interface extends the {@link Queue} interface. When a deque is * used as a queue, FIFO (First-In-First-Out) behavior results. Elements are * added at the end of the deque and removed from the beginning. The methods - * inherited from the <tt>Queue</tt> interface are precisely equivalent to - * <tt>Deque</tt> methods as indicated in the following table: + * inherited from the {@code Queue} interface are precisely equivalent to + * {@code Deque} methods as indicated in the following table: * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Comparison of Queue and Deque methods</caption> * <tr> - * <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td> - * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> + * <td ALIGN=CENTER> <b>{@code Queue} Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent {@code Deque} Method</b></td> * </tr> * <tr> * <td>{@link java.util.Queue#add add(e)}</td> @@ -135,13 +137,14 @@ * interface should be used in preference to the legacy {@link Stack} class. * When a deque is used as a stack, elements are pushed and popped from the * beginning of the deque. Stack methods are precisely equivalent to - * <tt>Deque</tt> methods as indicated in the table below: + * {@code Deque} methods as indicated in the table below: * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Comparison of Stack and Deque methods</caption> * <tr> * <td ALIGN=CENTER> <b>Stack Method</b></td> - * <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td> + * <td ALIGN=CENTER> <b>Equivalent {@code Deque} Method</b></td> * </tr> * <tr> * <td>{@link #push push(e)}</td> @@ -168,18 +171,18 @@ * <p>Unlike the {@link List} interface, this interface does not * provide support for indexed access to elements. * - * <p>While <tt>Deque</tt> implementations are not strictly required + * <p>While {@code Deque} implementations are not strictly required * to prohibit the insertion of null elements, they are strongly - * encouraged to do so. Users of any <tt>Deque</tt> implementations + * encouraged to do so. Users of any {@code Deque} implementations * that do allow null elements are strongly encouraged <i>not</i> to * take advantage of the ability to insert nulls. This is so because - * <tt>null</tt> is used as a special return value by various methods + * {@code null} is used as a special return value by various methods * to indicated that the deque is empty. * - * <p><tt>Deque</tt> implementations generally do not define - * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt> + * <p>{@code Deque} implementations generally do not define + * element-based versions of the {@code equals} and {@code hashCode} * methods, but instead inherit the identity-based versions from class - * <tt>Object</tt>. + * {@code Object}. * * <p>This interface is a member of the <a * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections @@ -190,13 +193,13 @@ * @since 1.6 * @param <E> the type of elements held in this collection */ - public interface Deque<E> extends Queue<E> { /** * Inserts the specified element at the front of this deque if it is - * possible to do so immediately without violating capacity restrictions. - * When using a capacity-restricted deque, it is generally preferable to - * use method {@link #offerFirst}. + * possible to do so immediately without violating capacity restrictions, + * throwing an {@code IllegalStateException} if no space is currently + * available. When using a capacity-restricted deque, it is generally + * preferable to use method {@link #offerFirst}. * * @param e the element to add * @throws IllegalStateException if the element cannot be added at this @@ -212,9 +215,10 @@ /** * Inserts the specified element at the end of this deque if it is - * possible to do so immediately without violating capacity restrictions. - * When using a capacity-restricted deque, it is generally preferable to - * use method {@link #offerLast}. + * possible to do so immediately without violating capacity restrictions, + * throwing an {@code IllegalStateException} if no space is currently + * available. When using a capacity-restricted deque, it is generally + * preferable to use method {@link #offerLast}. * * <p>This method is equivalent to {@link #add}. * @@ -237,8 +241,8 @@ * which can fail to insert an element only by throwing an exception. * * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> + * @return {@code true} if the element was added to this deque, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this deque * @throws NullPointerException if the specified element is null and this @@ -255,8 +259,8 @@ * which can fail to insert an element only by throwing an exception. * * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> + * @return {@code true} if the element was added to this deque, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this deque * @throws NullPointerException if the specified element is null and this @@ -288,17 +292,17 @@ /** * Retrieves and removes the first element of this deque, - * or returns <tt>null</tt> if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the head of this deque, or <tt>null</tt> if this deque is empty + * @return the head of this deque, or {@code null} if this deque is empty */ E pollFirst(); /** * Retrieves and removes the last element of this deque, - * or returns <tt>null</tt> if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the tail of this deque, or <tt>null</tt> if this deque is empty + * @return the tail of this deque, or {@code null} if this deque is empty */ E pollLast(); @@ -325,31 +329,31 @@ /** * Retrieves, but does not remove, the first element of this deque, - * or returns <tt>null</tt> if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the head of this deque, or <tt>null</tt> if this deque is empty + * @return the head of this deque, or {@code null} if this deque is empty */ E peekFirst(); /** * Retrieves, but does not remove, the last element of this deque, - * or returns <tt>null</tt> if this deque is empty. + * or returns {@code null} if this deque is empty. * - * @return the tail of this deque, or <tt>null</tt> if this deque is empty + * @return the tail of this deque, or {@code null} if this deque is empty */ E peekLast(); /** * Removes the first occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that + * More formally, removes the first element {@code e} such that * <tt>(o==null ? e==null : o.equals(e))</tt> * (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call + * @return {@code true} if an element was removed as a result of this call * @throws ClassCastException if the class of the specified element * is incompatible with this deque * (<a href="Collection.html#optional-restrictions">optional</a>) @@ -362,14 +366,14 @@ /** * Removes the last occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the last element <tt>e</tt> such that + * More formally, removes the last element {@code e} such that * <tt>(o==null ? e==null : o.equals(e))</tt> * (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call + * @return {@code true} if an element was removed as a result of this call * @throws ClassCastException if the class of the specified element * is incompatible with this deque * (<a href="Collection.html#optional-restrictions">optional</a>) @@ -385,15 +389,15 @@ * Inserts the specified element into the queue represented by this deque * (in other words, at the tail of this deque) if it is possible to do so * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if no space is currently available. + * {@code true} upon success and throwing an + * {@code IllegalStateException} if no space is currently available. * When using a capacity-restricted deque, it is generally preferable to * use {@link #offer(Object) offer}. * * <p>This method is equivalent to {@link #addLast}. * * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) * @throws IllegalStateException if the element cannot be added at this * time due to capacity restrictions * @throws ClassCastException if the class of the specified element @@ -409,7 +413,7 @@ * Inserts the specified element into the queue represented by this deque * (in other words, at the tail of this deque) if it is possible to do so * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and <tt>false</tt> if no space is currently + * {@code true} upon success and {@code false} if no space is currently * available. When using a capacity-restricted deque, this method is * generally preferable to the {@link #add} method, which can fail to * insert an element only by throwing an exception. @@ -417,8 +421,8 @@ * <p>This method is equivalent to {@link #offerLast}. * * @param e the element to add - * @return <tt>true</tt> if the element was added to this deque, else - * <tt>false</tt> + * @return {@code true} if the element was added to this deque, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this deque * @throws NullPointerException if the specified element is null and this @@ -444,11 +448,11 @@ /** * Retrieves and removes the head of the queue represented by this deque * (in other words, the first element of this deque), or returns - * <tt>null</tt> if this deque is empty. + * {@code null} if this deque is empty. * * <p>This method is equivalent to {@link #pollFirst()}. * - * @return the first element of this deque, or <tt>null</tt> if + * @return the first element of this deque, or {@code null} if * this deque is empty */ E poll(); @@ -469,12 +473,12 @@ /** * Retrieves, but does not remove, the head of the queue represented by * this deque (in other words, the first element of this deque), or - * returns <tt>null</tt> if this deque is empty. + * returns {@code null} if this deque is empty. * * <p>This method is equivalent to {@link #peekFirst()}. * * @return the head of the queue represented by this deque, or - * <tt>null</tt> if this deque is empty + * {@code null} if this deque is empty */ E peek(); @@ -484,9 +488,8 @@ /** * Pushes an element onto the stack represented by this deque (in other * words, at the head of this deque) if it is possible to do so - * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an - * <tt>IllegalStateException</tt> if no space is currently available. + * immediately without violating capacity restrictions, throwing an + * {@code IllegalStateException} if no space is currently available. * * <p>This method is equivalent to {@link #addFirst}. * @@ -520,16 +523,16 @@ /** * Removes the first occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element <tt>e</tt> such that + * More formally, removes the first element {@code e} such that * <tt>(o==null ? e==null : o.equals(e))</tt> * (if such an element exists). - * Returns <tt>true</tt> if this deque contained the specified element + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * - * <p>This method is equivalent to {@link #removeFirstOccurrence}. + * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}. * * @param o element to be removed from this deque, if present - * @return <tt>true</tt> if an element was removed as a result of this call + * @return {@code true} if an element was removed as a result of this call * @throws ClassCastException if the class of the specified element * is incompatible with this deque * (<a href="Collection.html#optional-restrictions">optional</a>) @@ -540,13 +543,13 @@ boolean remove(Object o); /** - * Returns <tt>true</tt> if this deque contains the specified element. - * More formally, returns <tt>true</tt> if and only if this deque contains - * at least one element <tt>e</tt> such that + * Returns {@code true} if this deque contains the specified element. + * More formally, returns {@code true} if and only if this deque contains + * at least one element {@code e} such that * <tt>(o==null ? e==null : o.equals(e))</tt>. * * @param o element whose presence in this deque is to be tested - * @return <tt>true</tt> if this deque contains the specified element + * @return {@code true} if this deque contains the specified element * @throws ClassCastException if the type of the specified element * is incompatible with this deque * (<a href="Collection.html#optional-restrictions">optional</a>)
--- a/src/share/classes/java/util/DoubleSummaryStatistics.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/DoubleSummaryStatistics.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,6 +25,7 @@ package java.util; import java.util.function.DoubleConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -35,24 +36,24 @@ * summary statistics on a stream of doubles with: * <pre> {@code * DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new, - * DoubleSummaryStatistics::accept, - * DoubleSummaryStatistics::combine); + * DoubleSummaryStatistics::accept, + * DoubleSummaryStatistics::combine); * }</pre> * * <p>{@code DoubleSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * * <pre> {@code * DoubleSummaryStatistics stats = people.stream() - * .collect(Collectors.toDoubleSummaryStatistics(Person::getWeight)); + * .collect(Collectors.summarizingDouble(Person::getWeight)); *}</pre> * * This computes, in a single pass, the count of people, as well as the minimum, * maximum, sum, and average of their weights. * * @implNote This implementation is not thread safe. However, it is safe to use - * {@link java.util.stream.Collectors#toDoubleSummaryStatistics(java.util.function.ToDoubleFunction) + * {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction) * Collectors.toDoubleStatistics()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for @@ -152,7 +153,7 @@ } /** - * Returns the average of values recorded, or zero if no values have been + * Returns the arithmetic mean of values recorded, or zero if no values have been * recorded. The average returned can vary depending upon the order in * which values are recorded. This is due to accumulated rounding error in * addition of values of differing magnitudes. Values sorted by increasing @@ -160,7 +161,7 @@ * value is a {@code NaN} or the sum is at any point a {@code NaN} then the * average will be {@code NaN}. * - * @return the average of values, or zero if none + * @return the arithmetic mean of values, or zero if none */ public final double getAverage() { return getCount() > 0 ? getSum() / getCount() : 0.0d;
--- a/src/share/classes/java/util/Formatter.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Formatter.java Wed Aug 07 19:56:20 2013 -0700 @@ -626,12 +626,11 @@ * <p> For general argument types, the precision is the maximum number of * characters to be written to the output. * - * <p> For the floating-point conversions {@code 'e'}, {@code 'E'}, and - * {@code 'f'} the precision is the number of digits after the decimal - * separator. If the conversion is {@code 'g'} or {@code 'G'}, then the + * <p> For the floating-point conversions {@code 'a'}, {@code 'A'}, {@code 'e'}, + * {@code 'E'}, and {@code 'f'} the precision is the number of digits after the + * radix point. If the conversion is {@code 'g'} or {@code 'G'}, then the * precision is the total number of digits in the resulting magnitude after - * rounding. If the conversion is {@code 'a'} or {@code 'A'}, then the - * precision must not be specified. + * rounding. * * <p> For character, integral, and date/time argument types and the percent * and line separator conversions, the precision is not applicable; if a @@ -1297,14 +1296,21 @@ * of the significand as a fraction. The exponent is represented by * {@code 'p'} (<tt>'\u0070'</tt>) followed by a decimal string of the * unbiased exponent as if produced by invoking {@link - * Integer#toString(int) Integer.toString} on the exponent value. + * Integer#toString(int) Integer.toString} on the exponent value. If the + * precision is specified, the value is rounded to the given number of + * hexadecimal digits. * * <li> If <i>m</i> is a {@code double} value with a subnormal - * representation then the significand is represented by the characters - * {@code '0x0.'} followed by the hexadecimal representation of the rest - * of the significand as a fraction. The exponent is represented by - * {@code 'p-1022'}. Note that there must be at least one nonzero digit - * in a subnormal significand. + * representation then, unless the precision is specified to be in the range + * 1 through 12, inclusive, the significand is represented by the characters + * {@code '0x0.'} followed by the hexadecimal representation of the rest of + * the significand as a fraction, and the exponent represented by + * {@code 'p-1022'}. If the precision is in the interval + * [1, 12], the subnormal value is normalized such that it + * begins with the characters {@code '0x1.'}, rounded to the number of + * hexadecimal digits of precision, and the exponent adjusted + * accordingly. Note that there must be at least one nonzero digit in a + * subnormal significand. * * </ul> * @@ -1367,7 +1373,7 @@ * {@code 1}. * * <p> If the conversion is {@code 'a'} or {@code 'A'}, then the precision - * is the number of hexadecimal digits after the decimal separator. If the + * is the number of hexadecimal digits after the radix point. If the * precision is not provided, then all of the digits as returned by {@link * Double#toHexString(double)} will be output. *
--- a/src/share/classes/java/util/HashMap.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/HashMap.java Wed Aug 07 19:56:20 2013 -0700 @@ -876,13 +876,9 @@ private static int roundUpToPowerOf2(int number) { // assert number >= 0 : "number must be non-negative"; - int rounded = number >= MAXIMUM_CAPACITY + return number >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY - : (rounded = Integer.highestOneBit(number)) != 0 - ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded - : 1; - - return rounded; + : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1; } /**
--- a/src/share/classes/java/util/Hashtable.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Hashtable.java Wed Aug 07 19:56:20 2013 -0700 @@ -928,6 +928,7 @@ return (null == result) ? defaultValue : result; } + @SuppressWarnings("unchecked") @Override public synchronized void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); // explicit check required in case @@ -947,6 +948,7 @@ } } + @SuppressWarnings("unchecked") @Override public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Objects.requireNonNull(function); // explicit check required in case
--- a/src/share/classes/java/util/IdentityHashMap.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/IdentityHashMap.java Wed Aug 07 19:56:20 2013 -0700 @@ -1339,6 +1339,7 @@ tab[i + 1] = value; } + @SuppressWarnings("unchecked") @Override public void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); @@ -1357,6 +1358,7 @@ } } + @SuppressWarnings("unchecked") @Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Objects.requireNonNull(function);
--- a/src/share/classes/java/util/IntSummaryStatistics.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/IntSummaryStatistics.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,6 +25,7 @@ package java.util; import java.util.function.IntConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -35,24 +36,24 @@ * summary statistics on a stream of ints with: * <pre> {@code * IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new, - * IntSummaryStatistics::accept, - * IntSummaryStatistics::combine); + * IntSummaryStatistics::accept, + * IntSummaryStatistics::combine); * }</pre> * * <p>{@code IntSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * * <pre> {@code * IntSummaryStatistics stats = people.stream() - * .collect(Collectors.toIntSummaryStatistics(Person::getDependents)); + * .collect(Collectors.summarizingInt(Person::getDependents)); *}</pre> * * This computes, in a single pass, the count of people, as well as the minimum, * maximum, sum, and average of their number of dependents. * * @implNote This implementation is not thread safe. However, it is safe to use - * {@link java.util.stream.Collectors#toIntSummaryStatistics(java.util.function.ToIntFunction) + * {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction) * Collectors.toIntStatistics()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for @@ -140,10 +141,10 @@ } /** - * Returns the average of values recorded, or zero if no values have been + * Returns the arithmetic mean of values recorded, or zero if no values have been * recorded. * - * @return the average of values, or zero if none + * @return the arithmetic mean of values, or zero if none */ public final double getAverage() { return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
--- a/src/share/classes/java/util/LongSummaryStatistics.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/LongSummaryStatistics.java Wed Aug 07 19:56:20 2013 -0700 @@ -26,6 +26,7 @@ import java.util.function.IntConsumer; import java.util.function.LongConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -36,24 +37,24 @@ * summary statistics on a stream of longs with: * <pre> {@code * LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new, - * LongSummaryStatistics::accept, - * LongSummaryStatistics::combine); + * LongSummaryStatistics::accept, + * LongSummaryStatistics::combine); * }</pre> * * <p>{@code LongSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector)} reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * * <pre> {@code * LongSummaryStatistics stats = people.stream() - * .collect(Collectors.toLongSummaryStatistics(Person::getAge)); + * .collect(Collectors.summarizingLong(Person::getAge)); *}</pre> * * This computes, in a single pass, the count of people, as well as the minimum, - * maximum, sum, and average of their ages in milliseconds. + * maximum, sum, and average of their ages. * * @implNote This implementation is not thread safe. However, it is safe to use - * {@link java.util.stream.Collectors#toLongSummaryStatistics(java.util.function.ToLongFunction) + * {@link java.util.stream.Collectors#summarizingLong(java.util.function.ToLongFunction) * Collectors.toLongStatistics()} on a parallel stream, because the parallel * implementation of {@link java.util.stream.Stream#collect Stream.collect()} * provides the necessary partitioning, isolation, and merging of results for @@ -152,10 +153,10 @@ } /** - * Returns the average of values recorded, or zero if no values have been + * Returns the arithmetic mean of values recorded, or zero if no values have been * recorded. * - * @return The average of values, or zero if none + * @return The arithmetic mean of values, or zero if none */ public final double getAverage() { return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
--- a/src/share/classes/java/util/Optional.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Optional.java Wed Aug 07 19:56:20 2013 -0700 @@ -307,7 +307,7 @@ return false; } - Optional other = (Optional) obj; + Optional<?> other = (Optional<?>) obj; return Objects.equals(value, other.value); }
--- a/src/share/classes/java/util/Queue.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Queue.java Wed Aug 07 19:56:20 2013 -0700 @@ -41,14 +41,15 @@ * queues provide additional insertion, extraction, and inspection * operations. Each of these methods exists in two forms: one throws * an exception if the operation fails, the other returns a special - * value (either <tt>null</tt> or <tt>false</tt>, depending on the + * value (either {@code null} or {@code false}, depending on the * operation). The latter form of the insert operation is designed - * specifically for use with capacity-restricted <tt>Queue</tt> + * specifically for use with capacity-restricted {@code Queue} * implementations; in most implementations, insert operations cannot * fail. * * <p> * <table BORDER CELLPADDING=3 CELLSPACING=1> + * <caption>Summary of Queue methods</caption> * <tr> * <td></td> * <td ALIGN=CENTER><em>Throws exception</em></td> @@ -56,18 +57,18 @@ * </tr> * <tr> * <td><b>Insert</b></td> - * <td>{@link #add add(e)}</td> - * <td>{@link #offer offer(e)}</td> + * <td>{@link Queue#add add(e)}</td> + * <td>{@link Queue#offer offer(e)}</td> * </tr> * <tr> * <td><b>Remove</b></td> - * <td>{@link #remove remove()}</td> - * <td>{@link #poll poll()}</td> + * <td>{@link Queue#remove remove()}</td> + * <td>{@link Queue#poll poll()}</td> * </tr> * <tr> * <td><b>Examine</b></td> - * <td>{@link #element element()}</td> - * <td>{@link #peek peek()}</td> + * <td>{@link Queue#element element()}</td> + * <td>{@link Queue#peek peek()}</td> * </tr> * </table> * @@ -79,15 +80,15 @@ * Whatever the ordering used, the <em>head</em> of the queue is that * element which would be removed by a call to {@link #remove() } or * {@link #poll()}. In a FIFO queue, all new elements are inserted at - * the <em> tail</em> of the queue. Other kinds of queues may use - * different placement rules. Every <tt>Queue</tt> implementation + * the <em>tail</em> of the queue. Other kinds of queues may use + * different placement rules. Every {@code Queue} implementation * must specify its ordering properties. * * <p>The {@link #offer offer} method inserts an element if possible, - * otherwise returning <tt>false</tt>. This differs from the {@link + * otherwise returning {@code false}. This differs from the {@link * java.util.Collection#add Collection.add} method, which can fail to * add an element only by throwing an unchecked exception. The - * <tt>offer</tt> method is designed for use when failure is a normal, + * {@code offer} method is designed for use when failure is a normal, * rather than exceptional occurrence, for example, in fixed-capacity * (or "bounded") queues. * @@ -95,32 +96,32 @@ * return the head of the queue. * Exactly which element is removed from the queue is a * function of the queue's ordering policy, which differs from - * implementation to implementation. The <tt>remove()</tt> and - * <tt>poll()</tt> methods differ only in their behavior when the - * queue is empty: the <tt>remove()</tt> method throws an exception, - * while the <tt>poll()</tt> method returns <tt>null</tt>. + * implementation to implementation. The {@code remove()} and + * {@code poll()} methods differ only in their behavior when the + * queue is empty: the {@code remove()} method throws an exception, + * while the {@code poll()} method returns {@code null}. * * <p>The {@link #element()} and {@link #peek()} methods return, but do * not remove, the head of the queue. * - * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue + * <p>The {@code Queue} interface does not define the <i>blocking queue * methods</i>, which are common in concurrent programming. These methods, * which wait for elements to appear or for space to become available, are * defined in the {@link java.util.concurrent.BlockingQueue} interface, which * extends this interface. * - * <p><tt>Queue</tt> implementations generally do not allow insertion - * of <tt>null</tt> elements, although some implementations, such as - * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>. - * Even in the implementations that permit it, <tt>null</tt> should - * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also - * used as a special return value by the <tt>poll</tt> method to + * <p>{@code Queue} implementations generally do not allow insertion + * of {@code null} elements, although some implementations, such as + * {@link LinkedList}, do not prohibit insertion of {@code null}. + * Even in the implementations that permit it, {@code null} should + * not be inserted into a {@code Queue}, as {@code null} is also + * used as a special return value by the {@code poll} method to * indicate that the queue contains no elements. * - * <p><tt>Queue</tt> implementations generally do not define - * element-based versions of methods <tt>equals</tt> and - * <tt>hashCode</tt> but instead inherit the identity based versions - * from class <tt>Object</tt>, because element-based equality is not + * <p>{@code Queue} implementations generally do not define + * element-based versions of methods {@code equals} and + * {@code hashCode} but instead inherit the identity based versions + * from class {@code Object}, because element-based equality is not * always well-defined for queues with the same elements but different * ordering properties. * @@ -145,11 +146,11 @@ /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions, returning - * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt> + * {@code true} upon success and throwing an {@code IllegalStateException} * if no space is currently available. * * @param e the element to add - * @return <tt>true</tt> (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) * @throws IllegalStateException if the element cannot be added at this * time due to capacity restrictions * @throws ClassCastException if the class of the specified element @@ -169,8 +170,8 @@ * by throwing an exception. * * @param e the element to add - * @return <tt>true</tt> if the element was added to this queue, else - * <tt>false</tt> + * @return {@code true} if the element was added to this queue, else + * {@code false} * @throws ClassCastException if the class of the specified element * prevents it from being added to this queue * @throws NullPointerException if the specified element is null and @@ -192,9 +193,9 @@ /** * Retrieves and removes the head of this queue, - * or returns <tt>null</tt> if this queue is empty. + * or returns {@code null} if this queue is empty. * - * @return the head of this queue, or <tt>null</tt> if this queue is empty + * @return the head of this queue, or {@code null} if this queue is empty */ E poll(); @@ -210,9 +211,9 @@ /** * Retrieves, but does not remove, the head of this queue, - * or returns <tt>null</tt> if this queue is empty. + * or returns {@code null} if this queue is empty. * - * @return the head of this queue, or <tt>null</tt> if this queue is empty + * @return the head of this queue, or {@code null} if this queue is empty */ E peek(); }
--- a/src/share/classes/java/util/StringJoiner.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/StringJoiner.java Wed Aug 07 19:56:20 2013 -0700 @@ -49,16 +49,17 @@ * <p> * A {@code StringJoiner} may be employed to create formatted output from a * {@link java.util.stream.Stream} using - * {@link java.util.stream.Collectors#toStringJoiner}. For example: + * {@link java.util.stream.Collectors#joining(CharSequence)}. For example: * * <pre> {@code * List<Integer> numbers = Arrays.asList(1, 2, 3, 4); * String commaSeparatedNumbers = numbers.stream() * .map(i -> i.toString()) - * .collect(Collectors.toStringJoiner(", ")).toString(); + * .collect(Collectors.joining(", ")); * }</pre> * - * @see java.util.stream.Collectors#toStringJoiner + * @see java.util.stream.Collectors#joining(CharSequence) + * @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence) * @since 1.8 */ public final class StringJoiner {
--- a/src/share/classes/java/util/Vector.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/Vector.java Wed Aug 07 19:56:20 2013 -0700 @@ -1164,12 +1164,13 @@ if (i >= size) { return; } - final Object[] elementData = Vector.this.elementData; + @SuppressWarnings("unchecked") + final E[] elementData = (E[]) Vector.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { - action.accept((E) elementData[i++]); + action.accept(elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; @@ -1311,8 +1312,8 @@ modCount++; } + @SuppressWarnings("unchecked") @Override - @SuppressWarnings("unchecked") public synchronized void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c);
--- a/src/share/classes/java/util/WeakHashMap.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/WeakHashMap.java Wed Aug 07 19:56:20 2013 -0700 @@ -1038,6 +1038,7 @@ } } + @SuppressWarnings("unchecked") @Override public void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); @@ -1059,6 +1060,7 @@ } } + @SuppressWarnings("unchecked") @Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Objects.requireNonNull(function);
--- a/src/share/classes/java/util/concurrent/CompletableFuture.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/concurrent/CompletableFuture.java Wed Aug 07 19:56:20 2013 -0700 @@ -48,13 +48,16 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; /** * A {@link Future} that may be explicitly completed (setting its - * value and status), and may include dependent functions and actions - * that trigger upon its completion. + * value and status), and may be used as a {@link CompletionStage}, + * supporting dependent functions and actions that trigger upon its + * completion. * * <p>When two or more threads attempt to * {@link #complete complete}, @@ -62,64 +65,50 @@ * {@link #cancel cancel} * a CompletableFuture, only one of them succeeds. * - * <p>Methods are available for adding dependents based on - * user-provided Functions, Consumers, or Runnables. The appropriate - * form to use depends on whether actions require arguments and/or - * produce results. Completion of a dependent action will trigger the - * completion of another CompletableFuture. Actions may also be - * triggered after either or both the current and another - * CompletableFuture complete. Multiple CompletableFutures may also - * be grouped as one using {@link #anyOf(CompletableFuture...)} and - * {@link #allOf(CompletableFuture...)}. + * <p>In addition to these and related methods for directly + * manipulating status and results, CompletableFuture implements + * interface {@link CompletionStage} with the following policies: <ul> * - * <p>CompletableFutures themselves do not execute asynchronously. - * However, actions supplied for dependent completions of another - * CompletableFuture may do so, depending on whether they are provided - * via one of the <em>async</em> methods (that is, methods with names - * of the form <tt><var>xxx</var>Async</tt>). The <em>async</em> - * methods provide a way to commence asynchronous processing of an - * action using either a given {@link Executor} or by default the - * {@link ForkJoinPool#commonPool()}. To simplify monitoring, + * <li>Actions supplied for dependent completions of + * <em>non-async</em> methods may be performed by the thread that + * completes the current CompletableFuture, or by any other caller of + * a completion method.</li> + * + * <li>All <em>async</em> methods without an explicit Executor + * argument are performed using the {@link ForkJoinPool#commonPool()} + * (unless it does not support a parallelism level of at least two, in + * which case, a new Thread is used). To simplify monitoring, * debugging, and tracking, all generated asynchronous tasks are - * instances of the marker interface {@link AsynchronousCompletionTask}. + * instances of the marker interface {@link + * AsynchronousCompletionTask}. </li> * - * <p>Actions supplied for dependent completions of <em>non-async</em> - * methods may be performed by the thread that completes the current - * CompletableFuture, or by any other caller of these methods. There - * are no guarantees about the order of processing completions unless - * constrained by these methods. + * <li>All CompletionStage methods are implemented independently of + * other public methods, so the behavior of one method is not impacted + * by overrides of others in subclasses. </li> </ul> * - * <p>Since (unlike {@link FutureTask}) this class has no direct - * control over the computation that causes it to be completed, - * cancellation is treated as just another form of exceptional completion. - * Method {@link #cancel cancel} has the same effect as - * {@code completeExceptionally(new CancellationException())}. + * <p>CompletableFuture also implements {@link Future} with the following + * policies: <ul> * - * <p>Upon exceptional completion (including cancellation), or when a - * completion entails an additional computation which terminates - * abruptly with an (unchecked) exception or error, then all of their - * dependent completions (and their dependents in turn) generally act - * as {@code completeExceptionally} with a {@link CompletionException} - * holding that exception as its cause. However, the {@link - * #exceptionally exceptionally} and {@link #handle handle} - * completions <em>are</em> able to handle exceptional completions of - * the CompletableFutures they depend on. + * <li>Since (unlike {@link FutureTask}) this class has no direct + * control over the computation that causes it to be completed, + * cancellation is treated as just another form of exceptional + * completion. Method {@link #cancel cancel} has the same effect as + * {@code completeExceptionally(new CancellationException())}. Method + * {@link #isCompletedExceptionally} can be used to determine if a + * CompletableFuture completed in any exceptional fashion.</li> * - * <p>In case of exceptional completion with a CompletionException, + * <li>In case of exceptional completion with a CompletionException, * methods {@link #get()} and {@link #get(long, TimeUnit)} throw an * {@link ExecutionException} with the same cause as held in the - * corresponding CompletionException. However, in these cases, - * methods {@link #join()} and {@link #getNow} throw the - * CompletionException, which simplifies usage. - * - * <p>Arguments used to pass a completion result (that is, for parameters - * of type {@code T}) may be null, but passing a null value for any other - * parameter will result in a {@link NullPointerException} being thrown. + * corresponding CompletionException. To simplify usage in most + * contexts, this class also defines methods {@link #join()} and + * {@link #getNow} that instead throw the CompletionException directly + * in these cases.</li> </ul> * * @author Doug Lea * @since 1.8 */ -public class CompletableFuture<T> implements Future<T> { +public class CompletableFuture<T> implements Future<T>, CompletionStage<T> { /* * Overview: @@ -438,6 +427,19 @@ public final void run() { exec(); } } + /** + * Starts the given async task using the given executor, unless + * the executor is ForkJoinPool.commonPool and it has been + * disabled, in which case starts a new thread. + */ + static void execAsync(Executor e, Async r) { + if (e == ForkJoinPool.commonPool() && + ForkJoinPool.getCommonPoolParallelism() <= 1) + new Thread(r).start(); + else + e.execute(r); + } + static final class AsyncRun extends Async { final Runnable fn; final CompletableFuture<Void> dst; @@ -538,13 +540,13 @@ static final class AsyncAccept<T> extends Async { final T arg; final Consumer<? super T> fn; - final CompletableFuture<Void> dst; + final CompletableFuture<?> dst; AsyncAccept(T arg, Consumer<? super T> fn, - CompletableFuture<Void> dst) { + CompletableFuture<?> dst) { this.arg = arg; this.fn = fn; this.dst = dst; } public final boolean exec() { - CompletableFuture<Void> d; Throwable ex; + CompletableFuture<?> d; Throwable ex; if ((d = this.dst) != null && d.result == null) { try { fn.accept(arg); @@ -563,14 +565,14 @@ final T arg1; final U arg2; final BiConsumer<? super T,? super U> fn; - final CompletableFuture<Void> dst; + final CompletableFuture<?> dst; AsyncAcceptBoth(T arg1, U arg2, BiConsumer<? super T,? super U> fn, - CompletableFuture<Void> dst) { + CompletableFuture<?> dst) { this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst; } public final boolean exec() { - CompletableFuture<Void> d; Throwable ex; + CompletableFuture<?> d; Throwable ex; if ((d = this.dst) != null && d.result == null) { try { fn.accept(arg1, arg2); @@ -587,10 +589,10 @@ static final class AsyncCompose<T,U> extends Async { final T arg; - final Function<? super T, CompletableFuture<U>> fn; + final Function<? super T, ? extends CompletionStage<U>> fn; final CompletableFuture<U> dst; AsyncCompose(T arg, - Function<? super T, CompletableFuture<U>> fn, + Function<? super T, ? extends CompletionStage<U>> fn, CompletableFuture<U> dst) { this.arg = arg; this.fn = fn; this.dst = dst; } @@ -598,7 +600,8 @@ CompletableFuture<U> d, fr; U u; Throwable ex; if ((d = this.dst) != null && d.result == null) { try { - fr = fn.apply(arg); + CompletionStage<U> cs = fn.apply(arg); + fr = (cs == null) ? null : cs.toCompletableFuture(); ex = (fr == null) ? new NullPointerException() : null; } catch (Throwable rex) { ex = rex; @@ -626,6 +629,33 @@ private static final long serialVersionUID = 5232453952276885070L; } + static final class AsyncWhenComplete<T> extends Async { + final T arg1; + final Throwable arg2; + final BiConsumer<? super T,? super Throwable> fn; + final CompletableFuture<T> dst; + AsyncWhenComplete(T arg1, Throwable arg2, + BiConsumer<? super T,? super Throwable> fn, + CompletableFuture<T> dst) { + this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst; + } + public final boolean exec() { + CompletableFuture<T> d; + if ((d = this.dst) != null && d.result == null) { + Throwable ex = arg2; + try { + fn.accept(arg1, ex); + } catch (Throwable rex) { + if (ex == null) + ex = rex; + } + d.internalComplete(arg1, ex); + } + return true; + } + private static final long serialVersionUID = 5232453952276885070L; + } + /* ------------- Completions -------------- */ /** @@ -680,7 +710,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncApply<T,U>(t, fn, dst)); + execAsync(e, new AsyncApply<T,U>(t, fn, dst)); else u = fn.apply(t); } catch (Throwable rex) { @@ -697,11 +727,11 @@ static final class ThenAccept<T> extends Completion { final CompletableFuture<? extends T> src; final Consumer<? super T> fn; - final CompletableFuture<Void> dst; + final CompletableFuture<?> dst; final Executor executor; ThenAccept(CompletableFuture<? extends T> src, Consumer<? super T> fn, - CompletableFuture<Void> dst, + CompletableFuture<?> dst, Executor executor) { this.src = src; this.fn = fn; this.dst = dst; this.executor = executor; @@ -709,7 +739,7 @@ public final void run() { final CompletableFuture<? extends T> a; final Consumer<? super T> fn; - final CompletableFuture<Void> dst; + final CompletableFuture<?> dst; Object r; T t; Throwable ex; if ((dst = this.dst) != null && (fn = this.fn) != null && @@ -729,7 +759,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncAccept<T>(t, fn, dst)); + execAsync(e, new AsyncAccept<T>(t, fn, dst)); else fn.accept(t); } catch (Throwable rex) { @@ -773,7 +803,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncRun(fn, dst)); + execAsync(e, new AsyncRun(fn, dst)); else fn.run(); } catch (Throwable rex) { @@ -839,7 +869,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncCombine<T,U,V>(t, u, fn, dst)); + execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst)); else v = fn.apply(t, u); } catch (Throwable rex) { @@ -904,7 +934,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncAcceptBoth<T,U>(t, u, fn, dst)); + execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst)); else fn.accept(t, u); } catch (Throwable rex) { @@ -956,7 +986,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncRun(fn, dst)); + execAsync(e, new AsyncRun(fn, dst)); else fn.run(); } catch (Throwable rex) { @@ -1042,7 +1072,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncApply<T,U>(t, fn, dst)); + execAsync(e, new AsyncApply<T,U>(t, fn, dst)); else u = fn.apply(t); } catch (Throwable rex) { @@ -1095,7 +1125,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncAccept<T>(t, fn, dst)); + execAsync(e, new AsyncAccept<T>(t, fn, dst)); else fn.accept(t); } catch (Throwable rex) { @@ -1143,7 +1173,7 @@ if (ex == null) { try { if (e != null) - e.execute(new AsyncRun(fn, dst)); + execAsync(e, new AsyncRun(fn, dst)); else fn.run(); } catch (Throwable rex) { @@ -1226,6 +1256,54 @@ private static final long serialVersionUID = 5232453952276885070L; } + static final class WhenCompleteCompletion<T> extends Completion { + final CompletableFuture<? extends T> src; + final BiConsumer<? super T, ? super Throwable> fn; + final CompletableFuture<T> dst; + final Executor executor; + WhenCompleteCompletion(CompletableFuture<? extends T> src, + BiConsumer<? super T, ? super Throwable> fn, + CompletableFuture<T> dst, + Executor executor) { + this.src = src; this.fn = fn; this.dst = dst; + this.executor = executor; + } + public final void run() { + final CompletableFuture<? extends T> a; + final BiConsumer<? super T, ? super Throwable> fn; + final CompletableFuture<T> dst; + Object r; T t; Throwable ex; + if ((dst = this.dst) != null && + (fn = this.fn) != null && + (a = this.src) != null && + (r = a.result) != null && + compareAndSet(0, 1)) { + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + Executor e = executor; + Throwable dx = null; + try { + if (e != null) + execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst)); + else + fn.accept(t, ex); + } catch (Throwable rex) { + dx = rex; + } + if (e == null || dx != null) + dst.internalComplete(t, ex != null ? ex : dx); + } + } + private static final long serialVersionUID = 5232453952276885070L; + } + static final class ThenCopy<T> extends Completion { final CompletableFuture<?> src; final CompletableFuture<T> dst; @@ -1286,10 +1364,13 @@ final CompletableFuture<? extends T> src; final BiFunction<? super T, Throwable, ? extends U> fn; final CompletableFuture<U> dst; + final Executor executor; HandleCompletion(CompletableFuture<? extends T> src, BiFunction<? super T, Throwable, ? extends U> fn, - CompletableFuture<U> dst) { + CompletableFuture<U> dst, + Executor executor) { this.src = src; this.fn = fn; this.dst = dst; + this.executor = executor; } public final void run() { final CompletableFuture<? extends T> a; @@ -1310,13 +1391,19 @@ @SuppressWarnings("unchecked") T tr = (T) r; t = tr; } - U u = null; Throwable dx = null; + Executor e = executor; + U u = null; + Throwable dx = null; try { - u = fn.apply(t, ex); + if (e != null) + execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst)); + else + u = fn.apply(t, ex); } catch (Throwable rex) { dx = rex; } - dst.internalComplete(u, dx); + if (e == null || dx != null) + dst.internalComplete(u, dx); } } private static final long serialVersionUID = 5232453952276885070L; @@ -1324,11 +1411,11 @@ static final class ThenCompose<T,U> extends Completion { final CompletableFuture<? extends T> src; - final Function<? super T, CompletableFuture<U>> fn; + final Function<? super T, ? extends CompletionStage<U>> fn; final CompletableFuture<U> dst; final Executor executor; ThenCompose(CompletableFuture<? extends T> src, - Function<? super T, CompletableFuture<U>> fn, + Function<? super T, ? extends CompletionStage<U>> fn, CompletableFuture<U> dst, Executor executor) { this.src = src; this.fn = fn; this.dst = dst; @@ -1336,7 +1423,7 @@ } public final void run() { final CompletableFuture<? extends T> a; - final Function<? super T, CompletableFuture<U>> fn; + final Function<? super T, ? extends CompletionStage<U>> fn; final CompletableFuture<U> dst; Object r; T t; Throwable ex; Executor e; if ((dst = this.dst) != null && @@ -1358,10 +1445,12 @@ boolean complete = false; if (ex == null) { if ((e = executor) != null) - e.execute(new AsyncCompose<T,U>(t, fn, dst)); + execAsync(e, new AsyncCompose<T,U>(t, fn, dst)); else { try { - if ((c = fn.apply(t)) == null) + CompletionStage<U> cs = fn.apply(t); + c = (cs == null) ? null : cs.toCompletableFuture(); + if (c == null) ex = new NullPointerException(); } catch (Throwable rex) { ex = rex; @@ -1401,6 +1490,619 @@ private static final long serialVersionUID = 5232453952276885070L; } + // Implementations of stage methods with (plain, async, Executor) forms + + private <U> CompletableFuture<U> doThenApply + (Function<? super T,? extends U> fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture<U> dst = new CompletableFuture<U>(); + ThenApply<T,U> d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = new CompletionNode + (d = new ThenApply<T,U>(this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + U u = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncApply<T,U>(t, fn, dst)); + else + u = fn.apply(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(u, ex); + } + helpPostComplete(); + return dst; + } + + private CompletableFuture<Void> doThenAccept(Consumer<? super T> fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture<Void> dst = new CompletableFuture<Void>(); + ThenAccept<T> d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = new CompletionNode + (d = new ThenAccept<T>(this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncAccept<T>(t, fn, dst)); + else + fn.accept(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + return dst; + } + + private CompletableFuture<Void> doThenRun(Runnable action, + Executor e) { + if (action == null) throw new NullPointerException(); + CompletableFuture<Void> dst = new CompletableFuture<Void>(); + ThenRun d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = new CompletionNode + (d = new ThenRun(this, action, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + Throwable ex; + if (r instanceof AltResult) + ex = ((AltResult)r).ex; + else + ex = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncRun(action, dst)); + else + action.run(); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + return dst; + } + + private <U,V> CompletableFuture<V> doThenCombine + (CompletableFuture<? extends U> other, + BiFunction<? super T,? super U,? extends V> fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture<V> dst = new CompletableFuture<V>(); + ThenCombine<T,U,V> d = null; + Object r, s = null; + if ((r = result) == null || (s = other.result) == null) { + d = new ThenCombine<T,U,V>(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r == null && (r = result) == null) || + (s == null && (s = other.result) == null)) { + if (q != null) { + if (s != null || + UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (r != null || + UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) { + if (s != null) + break; + q = new CompletionNode(d); + } + } + } + if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { + T t; U u; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex != null) + u = null; + else if (s instanceof AltResult) { + ex = ((AltResult)s).ex; + u = null; + } + else { + @SuppressWarnings("unchecked") U us = (U) s; + u = us; + } + V v = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst)); + else + v = fn.apply(t, u); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(v, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private <U> CompletableFuture<Void> doThenAcceptBoth + (CompletableFuture<? extends U> other, + BiConsumer<? super T,? super U> fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture<Void> dst = new CompletableFuture<Void>(); + ThenAcceptBoth<T,U> d = null; + Object r, s = null; + if ((r = result) == null || (s = other.result) == null) { + d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r == null && (r = result) == null) || + (s == null && (s = other.result) == null)) { + if (q != null) { + if (s != null || + UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (r != null || + UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) { + if (s != null) + break; + q = new CompletionNode(d); + } + } + } + if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { + T t; U u; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex != null) + u = null; + else if (s instanceof AltResult) { + ex = ((AltResult)s).ex; + u = null; + } + else { + @SuppressWarnings("unchecked") U us = (U) s; + u = us; + } + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst)); + else + fn.accept(t, u); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture<Void> doRunAfterBoth(CompletableFuture<?> other, + Runnable action, + Executor e) { + if (other == null || action == null) throw new NullPointerException(); + CompletableFuture<Void> dst = new CompletableFuture<Void>(); + RunAfterBoth d = null; + Object r, s = null; + if ((r = result) == null || (s = other.result) == null) { + d = new RunAfterBoth(this, other, action, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r == null && (r = result) == null) || + (s == null && (s = other.result) == null)) { + if (q != null) { + if (s != null || + UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (r != null || + UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) { + if (s != null) + break; + q = new CompletionNode(d); + } + } + } + if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { + Throwable ex; + if (r instanceof AltResult) + ex = ((AltResult)r).ex; + else + ex = null; + if (ex == null && (s instanceof AltResult)) + ex = ((AltResult)s).ex; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncRun(action, dst)); + else + action.run(); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private <U> CompletableFuture<U> doApplyToEither + (CompletableFuture<? extends T> other, + Function<? super T, U> fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture<U> dst = new CompletableFuture<U>(); + ApplyToEither<T,U> d = null; + Object r; + if ((r = result) == null && (r = other.result) == null) { + d = new ApplyToEither<T,U>(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r = result) == null && (r = other.result) == null) { + if (q != null) { + if (UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + q = new CompletionNode(d); + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + U u = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncApply<T,U>(t, fn, dst)); + else + u = fn.apply(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(u, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture<Void> doAcceptEither + (CompletableFuture<? extends T> other, + Consumer<? super T> fn, + Executor e) { + if (other == null || fn == null) throw new NullPointerException(); + CompletableFuture<Void> dst = new CompletableFuture<Void>(); + AcceptEither<T> d = null; + Object r; + if ((r = result) == null && (r = other.result) == null) { + d = new AcceptEither<T>(this, other, fn, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r = result) == null && (r = other.result) == null) { + if (q != null) { + if (UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + q = new CompletionNode(d); + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncAccept<T>(t, fn, dst)); + else + fn.accept(t); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private CompletableFuture<Void> doRunAfterEither + (CompletableFuture<?> other, + Runnable action, + Executor e) { + if (other == null || action == null) throw new NullPointerException(); + CompletableFuture<Void> dst = new CompletableFuture<Void>(); + RunAfterEither d = null; + Object r; + if ((r = result) == null && (r = other.result) == null) { + d = new RunAfterEither(this, other, action, dst, e); + CompletionNode q = null, p = new CompletionNode(d); + while ((r = result) == null && (r = other.result) == null) { + if (q != null) { + if (UNSAFE.compareAndSwapObject + (other, COMPLETIONS, q.next = other.completions, q)) + break; + } + else if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + q = new CompletionNode(d); + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + Throwable ex; + if (r instanceof AltResult) + ex = ((AltResult)r).ex; + else + ex = null; + if (ex == null) { + try { + if (e != null) + execAsync(e, new AsyncRun(action, dst)); + else + action.run(); + } catch (Throwable rex) { + ex = rex; + } + } + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + other.helpPostComplete(); + return dst; + } + + private <U> CompletableFuture<U> doThenCompose + (Function<? super T, ? extends CompletionStage<U>> fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture<U> dst = null; + ThenCompose<T,U> d = null; + Object r; + if ((r = result) == null) { + dst = new CompletableFuture<U>(); + CompletionNode p = new CompletionNode + (d = new ThenCompose<T,U>(this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject + (this, COMPLETIONS, p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + if (ex == null) { + if (e != null) { + if (dst == null) + dst = new CompletableFuture<U>(); + execAsync(e, new AsyncCompose<T,U>(t, fn, dst)); + } + else { + try { + CompletionStage<U> cs = fn.apply(t); + if (cs == null || + (dst = cs.toCompletableFuture()) == null) + ex = new NullPointerException(); + } catch (Throwable rex) { + ex = rex; + } + } + } + if (dst == null) + dst = new CompletableFuture<U>(); + if (e == null || ex != null) + dst.internalComplete(null, ex); + } + helpPostComplete(); + dst.helpPostComplete(); + return dst; + } + + private CompletableFuture<T> doWhenComplete + (BiConsumer<? super T, ? super Throwable> fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture<T> dst = new CompletableFuture<T>(); + WhenCompleteCompletion<T> d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = + new CompletionNode(d = new WhenCompleteCompletion<T> + (this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, + p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + Throwable dx = null; + try { + if (e != null) + execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst)); + else + fn.accept(t, ex); + } catch (Throwable rex) { + dx = rex; + } + if (e == null || dx != null) + dst.internalComplete(t, ex != null ? ex : dx); + } + helpPostComplete(); + return dst; + } + + private <U> CompletableFuture<U> doHandle + (BiFunction<? super T, Throwable, ? extends U> fn, + Executor e) { + if (fn == null) throw new NullPointerException(); + CompletableFuture<U> dst = new CompletableFuture<U>(); + HandleCompletion<T,U> d = null; + Object r; + if ((r = result) == null) { + CompletionNode p = + new CompletionNode(d = new HandleCompletion<T,U> + (this, fn, dst, e)); + while ((r = result) == null) { + if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, + p.next = completions, p)) + break; + } + } + if (r != null && (d == null || d.compareAndSet(0, 1))) { + T t; Throwable ex; + if (r instanceof AltResult) { + ex = ((AltResult)r).ex; + t = null; + } + else { + ex = null; + @SuppressWarnings("unchecked") T tr = (T) r; + t = tr; + } + U u = null; + Throwable dx = null; + try { + if (e != null) + execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst)); + else { + u = fn.apply(t, ex); + dx = null; + } + } catch (Throwable rex) { + dx = rex; + u = null; + } + if (e == null || dx != null) + dst.internalComplete(u, dx); + } + helpPostComplete(); + return dst; + } + + // public methods /** @@ -1416,13 +2118,13 @@ * * @param supplier a function returning the value to be used * to complete the returned CompletableFuture + * @param <U> the function's return type * @return the new CompletableFuture */ public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) { if (supplier == null) throw new NullPointerException(); CompletableFuture<U> f = new CompletableFuture<U>(); - ForkJoinPool.commonPool(). - execute((ForkJoinTask<?>)new AsyncSupply<U>(supplier, f)); + execAsync(ForkJoinPool.commonPool(), new AsyncSupply<U>(supplier, f)); return f; } @@ -1434,6 +2136,7 @@ * @param supplier a function returning the value to be used * to complete the returned CompletableFuture * @param executor the executor to use for asynchronous execution + * @param <U> the function's return type * @return the new CompletableFuture */ public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, @@ -1441,7 +2144,7 @@ if (executor == null || supplier == null) throw new NullPointerException(); CompletableFuture<U> f = new CompletableFuture<U>(); - executor.execute(new AsyncSupply<U>(supplier, f)); + execAsync(executor, new AsyncSupply<U>(supplier, f)); return f; } @@ -1457,8 +2160,7 @@ public static CompletableFuture<Void> runAsync(Runnable runnable) { if (runnable == null) throw new NullPointerException(); CompletableFuture<Void> f = new CompletableFuture<Void>(); - ForkJoinPool.commonPool(). - execute((ForkJoinTask<?>)new AsyncRun(runnable, f)); + execAsync(ForkJoinPool.commonPool(), new AsyncRun(runnable, f)); return f; } @@ -1477,7 +2179,7 @@ if (executor == null || runnable == null) throw new NullPointerException(); CompletableFuture<Void> f = new CompletableFuture<Void>(); - executor.execute(new AsyncRun(runnable, f)); + execAsync(executor, new AsyncRun(runnable, f)); return f; } @@ -1486,6 +2188,7 @@ * the given value. * * @param value the value + * @param <U> the type of the value * @return the completed CompletableFuture */ public static <U> CompletableFuture<U> completedFuture(U value) { @@ -1657,60 +2360,18 @@ return triggered; } - /** - * Returns a new CompletableFuture that is completed - * when this CompletableFuture completes, with the result of the - * given function of this CompletableFuture's result. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied function throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ - public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) { + // CompletionStage methods + + public <U> CompletableFuture<U> thenApply + (Function<? super T,? extends U> fn) { return doThenApply(fn, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, with the result of the - * given function of this CompletableFuture's result from a - * task running in the {@link ForkJoinPool#commonPool()}. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied function throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ public <U> CompletableFuture<U> thenApplyAsync (Function<? super T,? extends U> fn) { return doThenApply(fn, ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, with the result of the - * given function of this CompletableFuture's result from a - * task running in the given executor. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied function throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ public <U> CompletableFuture<U> thenApplyAsync (Function<? super T,? extends U> fn, Executor executor) { @@ -1718,1149 +2379,228 @@ return doThenApply(fn, executor); } - private <U> CompletableFuture<U> doThenApply - (Function<? super T,? extends U> fn, - Executor e) { - if (fn == null) throw new NullPointerException(); - CompletableFuture<U> dst = new CompletableFuture<U>(); - ThenApply<T,U> d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = new CompletionNode - (d = new ThenApply<T,U>(this, fn, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - U u = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncApply<T,U>(t, fn, dst)); - else - u = fn.apply(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(u, ex); - } - helpPostComplete(); - return dst; + public CompletableFuture<Void> thenAccept + (Consumer<? super T> action) { + return doThenAccept(action, null); } - /** - * Returns a new CompletableFuture that is completed - * when this CompletableFuture completes, after performing the given - * action with this CompletableFuture's result. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> thenAccept(Consumer<? super T> block) { - return doThenAccept(block, null); + public CompletableFuture<Void> thenAcceptAsync + (Consumer<? super T> action) { + return doThenAccept(action, ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action with this CompletableFuture's result from a task running - * in the {@link ForkJoinPool#commonPool()}. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> block) { - return doThenAccept(block, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action with this CompletableFuture's result from a task running - * in the given executor. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param block the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> block, - Executor executor) { + public CompletableFuture<Void> thenAcceptAsync + (Consumer<? super T> action, + Executor executor) { if (executor == null) throw new NullPointerException(); - return doThenAccept(block, executor); + return doThenAccept(action, executor); } - private CompletableFuture<Void> doThenAccept(Consumer<? super T> fn, - Executor e) { - if (fn == null) throw new NullPointerException(); - CompletableFuture<Void> dst = new CompletableFuture<Void>(); - ThenAccept<T> d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = new CompletionNode - (d = new ThenAccept<T>(this, fn, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncAccept<T>(t, fn, dst)); - else - fn.accept(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - return dst; - } - - /** - * Returns a new CompletableFuture that is completed - * when this CompletableFuture completes, after performing the given - * action. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> thenRun(Runnable action) { + public CompletableFuture<Void> thenRun + (Runnable action) { return doThenRun(action, null); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action from a task running in the {@link ForkJoinPool#commonPool()}. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> thenRunAsync(Runnable action) { + public CompletableFuture<Void> thenRunAsync + (Runnable action) { return doThenRun(action, ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when this CompletableFuture completes, after performing the given - * action from a task running in the given executor. - * - * <p>If this CompletableFuture completes exceptionally, or the - * supplied action throws an exception, then the returned - * CompletableFuture completes exceptionally with a - * CompletionException holding the exception as its cause. - * - * @param action the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture<Void> thenRunAsync(Runnable action, - Executor executor) { + public CompletableFuture<Void> thenRunAsync + (Runnable action, + Executor executor) { if (executor == null) throw new NullPointerException(); return doThenRun(action, executor); } - private CompletableFuture<Void> doThenRun(Runnable action, - Executor e) { - if (action == null) throw new NullPointerException(); - CompletableFuture<Void> dst = new CompletableFuture<Void>(); - ThenRun d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = new CompletionNode - (d = new ThenRun(this, action, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - Throwable ex; - if (r instanceof AltResult) - ex = ((AltResult)r).ex; - else - ex = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncRun(action, dst)); - else - action.run(); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - return dst; + public <U,V> CompletableFuture<V> thenCombine + (CompletionStage<? extends U> other, + BiFunction<? super T,? super U,? extends V> fn) { + return doThenCombine(other.toCompletableFuture(), fn, null); } - /** - * Returns a new CompletableFuture that is completed - * when both this and the other given CompletableFuture complete, - * with the result of the given function of the results of the two - * CompletableFutures. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied function throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ - public <U,V> CompletableFuture<V> thenCombine - (CompletableFuture<? extends U> other, + public <U,V> CompletableFuture<V> thenCombineAsync + (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn) { - return doThenCombine(other, fn, null); + return doThenCombine(other.toCompletableFuture(), fn, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * with the result of the given function of the results of the two - * CompletableFutures from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied function throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ public <U,V> CompletableFuture<V> thenCombineAsync - (CompletableFuture<? extends U> other, - BiFunction<? super T,? super U,? extends V> fn) { - return doThenCombine(other, fn, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * with the result of the given function of the results of the two - * CompletableFutures from a task running in the given executor. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied function throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public <U,V> CompletableFuture<V> thenCombineAsync - (CompletableFuture<? extends U> other, + (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor) { if (executor == null) throw new NullPointerException(); - return doThenCombine(other, fn, executor); + return doThenCombine(other.toCompletableFuture(), fn, executor); + } + + public <U> CompletableFuture<Void> thenAcceptBoth + (CompletionStage<? extends U> other, + BiConsumer<? super T, ? super U> action) { + return doThenAcceptBoth(other.toCompletableFuture(), action, null); } - private <U,V> CompletableFuture<V> doThenCombine - (CompletableFuture<? extends U> other, - BiFunction<? super T,? super U,? extends V> fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture<V> dst = new CompletableFuture<V>(); - ThenCombine<T,U,V> d = null; - Object r, s = null; - if ((r = result) == null || (s = other.result) == null) { - d = new ThenCombine<T,U,V>(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r == null && (r = result) == null) || - (s == null && (s = other.result) == null)) { - if (q != null) { - if (s != null || - UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (r != null || - UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) { - if (s != null) - break; - q = new CompletionNode(d); - } - } - } - if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { - T t; U u; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex != null) - u = null; - else if (s instanceof AltResult) { - ex = ((AltResult)s).ex; - u = null; - } - else { - @SuppressWarnings("unchecked") U us = (U) s; - u = us; - } - V v = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncCombine<T,U,V>(t, u, fn, dst)); - else - v = fn.apply(t, u); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(v, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; + public <U> CompletableFuture<Void> thenAcceptBothAsync + (CompletionStage<? extends U> other, + BiConsumer<? super T, ? super U> action) { + return doThenAcceptBoth(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is completed - * when both this and the other given CompletableFuture complete, - * after performing the given action with the results of the two - * CompletableFutures. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public <U> CompletableFuture<Void> thenAcceptBoth - (CompletableFuture<? extends U> other, - BiConsumer<? super T, ? super U> block) { - return doThenAcceptBoth(other, block, null); + public <U> CompletableFuture<Void> thenAcceptBothAsync + (CompletionStage<? extends U> other, + BiConsumer<? super T, ? super U> action, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doThenAcceptBoth(other.toCompletableFuture(), action, executor); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action with the results of the two - * CompletableFutures from a task running in the {@link - * ForkJoinPool#commonPool()}. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public <U> CompletableFuture<Void> thenAcceptBothAsync - (CompletableFuture<? extends U> other, - BiConsumer<? super T, ? super U> block) { - return doThenAcceptBoth(other, block, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action with the results of the two - * CompletableFutures from a task running in the given executor. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public <U> CompletableFuture<Void> thenAcceptBothAsync - (CompletableFuture<? extends U> other, - BiConsumer<? super T, ? super U> block, - Executor executor) { - if (executor == null) throw new NullPointerException(); - return doThenAcceptBoth(other, block, executor); + public CompletableFuture<Void> runAfterBoth + (CompletionStage<?> other, + Runnable action) { + return doRunAfterBoth(other.toCompletableFuture(), action, null); } - private <U> CompletableFuture<Void> doThenAcceptBoth - (CompletableFuture<? extends U> other, - BiConsumer<? super T,? super U> fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture<Void> dst = new CompletableFuture<Void>(); - ThenAcceptBoth<T,U> d = null; - Object r, s = null; - if ((r = result) == null || (s = other.result) == null) { - d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r == null && (r = result) == null) || - (s == null && (s = other.result) == null)) { - if (q != null) { - if (s != null || - UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (r != null || - UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) { - if (s != null) - break; - q = new CompletionNode(d); - } - } - } - if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { - T t; U u; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex != null) - u = null; - else if (s instanceof AltResult) { - ex = ((AltResult)s).ex; - u = null; - } - else { - @SuppressWarnings("unchecked") U us = (U) s; - u = us; - } - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncAcceptBoth<T,U>(t, u, fn, dst)); - else - fn.accept(t, u); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; + public CompletableFuture<Void> runAfterBothAsync + (CompletionStage<?> other, + Runnable action) { + return doRunAfterBoth(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is completed - * when both this and the other given CompletableFuture complete, - * after performing the given action. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> runAfterBoth(CompletableFuture<?> other, - Runnable action) { - return doRunAfterBoth(other, action, null); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> runAfterBothAsync(CompletableFuture<?> other, - Runnable action) { - return doRunAfterBoth(other, action, ForkJoinPool.commonPool()); + public CompletableFuture<Void> runAfterBothAsync + (CompletionStage<?> other, + Runnable action, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doRunAfterBoth(other.toCompletableFuture(), action, executor); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when both this and the other given CompletableFuture complete, - * after performing the given action from a task running in the - * given executor. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, or the supplied action throws an exception, - * then the returned CompletableFuture completes exceptionally - * with a CompletionException holding the exception as its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture<Void> runAfterBothAsync(CompletableFuture<?> other, - Runnable action, - Executor executor) { - if (executor == null) throw new NullPointerException(); - return doRunAfterBoth(other, action, executor); - } - private CompletableFuture<Void> doRunAfterBoth(CompletableFuture<?> other, - Runnable action, - Executor e) { - if (other == null || action == null) throw new NullPointerException(); - CompletableFuture<Void> dst = new CompletableFuture<Void>(); - RunAfterBoth d = null; - Object r, s = null; - if ((r = result) == null || (s = other.result) == null) { - d = new RunAfterBoth(this, other, action, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r == null && (r = result) == null) || - (s == null && (s = other.result) == null)) { - if (q != null) { - if (s != null || - UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (r != null || - UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) { - if (s != null) - break; - q = new CompletionNode(d); - } - } - } - if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { - Throwable ex; - if (r instanceof AltResult) - ex = ((AltResult)r).ex; - else - ex = null; - if (ex == null && (s instanceof AltResult)) - ex = ((AltResult)s).ex; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncRun(action, dst)); - else - action.run(); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; + public <U> CompletableFuture<U> applyToEither + (CompletionStage<? extends T> other, + Function<? super T, U> fn) { + return doApplyToEither(other.toCompletableFuture(), fn, null); } - /** - * Returns a new CompletableFuture that is completed - * when either this or the other given CompletableFuture completes, - * with the result of the given function of either this or the other - * CompletableFuture's result. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied function - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ - public <U> CompletableFuture<U> applyToEither - (CompletableFuture<? extends T> other, + public <U> CompletableFuture<U> applyToEitherAsync + (CompletionStage<? extends T> other, Function<? super T, U> fn) { - return doApplyToEither(other, fn, null); + return doApplyToEither(other.toCompletableFuture(), fn, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * with the result of the given function of either this or the other - * CompletableFuture's result from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied function - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @return the new CompletableFuture - */ public <U> CompletableFuture<U> applyToEitherAsync - (CompletableFuture<? extends T> other, - Function<? super T, U> fn) { - return doApplyToEither(other, fn, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * with the result of the given function of either this or the other - * CompletableFuture's result from a task running in the - * given executor. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied function - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param fn the function to use to compute the value of - * the returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public <U> CompletableFuture<U> applyToEitherAsync - (CompletableFuture<? extends T> other, + (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor) { if (executor == null) throw new NullPointerException(); - return doApplyToEither(other, fn, executor); + return doApplyToEither(other.toCompletableFuture(), fn, executor); } - private <U> CompletableFuture<U> doApplyToEither - (CompletableFuture<? extends T> other, - Function<? super T, U> fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture<U> dst = new CompletableFuture<U>(); - ApplyToEither<T,U> d = null; - Object r; - if ((r = result) == null && (r = other.result) == null) { - d = new ApplyToEither<T,U>(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r = result) == null && (r = other.result) == null) { - if (q != null) { - if (UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - q = new CompletionNode(d); - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - U u = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncApply<T,U>(t, fn, dst)); - else - u = fn.apply(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(u, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; + public CompletableFuture<Void> acceptEither + (CompletionStage<? extends T> other, + Consumer<? super T> action) { + return doAcceptEither(other.toCompletableFuture(), action, null); } - /** - * Returns a new CompletableFuture that is completed - * when either this or the other given CompletableFuture completes, - * after performing the given action with the result of either this - * or the other CompletableFuture's result. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> acceptEither - (CompletableFuture<? extends T> other, - Consumer<? super T> block) { - return doAcceptEither(other, block, null); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action with the result of either this - * or the other CompletableFuture's result from a task running in - * the {@link ForkJoinPool#commonPool()}. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture<Void> acceptEitherAsync - (CompletableFuture<? extends T> other, - Consumer<? super T> block) { - return doAcceptEither(other, block, ForkJoinPool.commonPool()); + (CompletionStage<? extends T> other, + Consumer<? super T> action) { + return doAcceptEither(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action with the result of either this - * or the other CompletableFuture's result from a task running in - * the given executor. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param block the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ public CompletableFuture<Void> acceptEitherAsync - (CompletableFuture<? extends T> other, - Consumer<? super T> block, + (CompletionStage<? extends T> other, + Consumer<? super T> action, Executor executor) { if (executor == null) throw new NullPointerException(); - return doAcceptEither(other, block, executor); + return doAcceptEither(other.toCompletableFuture(), action, executor); } - private CompletableFuture<Void> doAcceptEither - (CompletableFuture<? extends T> other, - Consumer<? super T> fn, - Executor e) { - if (other == null || fn == null) throw new NullPointerException(); - CompletableFuture<Void> dst = new CompletableFuture<Void>(); - AcceptEither<T> d = null; - Object r; - if ((r = result) == null && (r = other.result) == null) { - d = new AcceptEither<T>(this, other, fn, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r = result) == null && (r = other.result) == null) { - if (q != null) { - if (UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - q = new CompletionNode(d); - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncAccept<T>(t, fn, dst)); - else - fn.accept(t); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; + public CompletableFuture<Void> runAfterEither(CompletionStage<?> other, + Runnable action) { + return doRunAfterEither(other.toCompletableFuture(), action, null); } - /** - * Returns a new CompletableFuture that is completed - * when either this or the other given CompletableFuture completes, - * after performing the given action. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public CompletableFuture<Void> runAfterEither(CompletableFuture<?> other, - Runnable action) { - return doRunAfterEither(other, action, null); + public CompletableFuture<Void> runAfterEitherAsync + (CompletionStage<?> other, + Runnable action) { + return doRunAfterEither(other.toCompletableFuture(), action, + ForkJoinPool.commonPool()); } - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action from a task running in the - * {@link ForkJoinPool#commonPool()}. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @return the new CompletableFuture - */ public CompletableFuture<Void> runAfterEitherAsync - (CompletableFuture<?> other, - Runnable action) { - return doRunAfterEither(other, action, ForkJoinPool.commonPool()); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * when either this or the other given CompletableFuture completes, - * after performing the given action from a task running in the - * given executor. - * - * <p>If this and/or the other CompletableFuture complete - * exceptionally, then the returned CompletableFuture may also do so, - * with a CompletionException holding one of these exceptions as its - * cause. No guarantees are made about which result or exception is - * used in the returned CompletableFuture. If the supplied action - * throws an exception, then the returned CompletableFuture completes - * exceptionally with a CompletionException holding the exception as - * its cause. - * - * @param other the other CompletableFuture - * @param action the action to perform before completing the - * returned CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the new CompletableFuture - */ - public CompletableFuture<Void> runAfterEitherAsync - (CompletableFuture<?> other, + (CompletionStage<?> other, Runnable action, Executor executor) { if (executor == null) throw new NullPointerException(); - return doRunAfterEither(other, action, executor); + return doRunAfterEither(other.toCompletableFuture(), action, executor); } - private CompletableFuture<Void> doRunAfterEither - (CompletableFuture<?> other, - Runnable action, - Executor e) { - if (other == null || action == null) throw new NullPointerException(); - CompletableFuture<Void> dst = new CompletableFuture<Void>(); - RunAfterEither d = null; - Object r; - if ((r = result) == null && (r = other.result) == null) { - d = new RunAfterEither(this, other, action, dst, e); - CompletionNode q = null, p = new CompletionNode(d); - while ((r = result) == null && (r = other.result) == null) { - if (q != null) { - if (UNSAFE.compareAndSwapObject - (other, COMPLETIONS, q.next = other.completions, q)) - break; - } - else if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - q = new CompletionNode(d); - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - Throwable ex; - if (r instanceof AltResult) - ex = ((AltResult)r).ex; - else - ex = null; - if (ex == null) { - try { - if (e != null) - e.execute(new AsyncRun(action, dst)); - else - action.run(); - } catch (Throwable rex) { - ex = rex; - } - } - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - other.helpPostComplete(); - return dst; - } - - /** - * Returns a CompletableFuture that upon completion, has the same - * value as produced by the given function of the result of this - * CompletableFuture. - * - * <p>If this CompletableFuture completes exceptionally, then the - * returned CompletableFuture also does so, with a - * CompletionException holding this exception as its cause. - * Similarly, if the computed CompletableFuture completes - * exceptionally, then so does the returned CompletableFuture. - * - * @param fn the function returning a new CompletableFuture - * @return the CompletableFuture - */ public <U> CompletableFuture<U> thenCompose - (Function<? super T, CompletableFuture<U>> fn) { + (Function<? super T, ? extends CompletionStage<U>> fn) { return doThenCompose(fn, null); } - /** - * Returns a CompletableFuture that upon completion, has the same - * value as that produced asynchronously using the {@link - * ForkJoinPool#commonPool()} by the given function of the result - * of this CompletableFuture. - * - * <p>If this CompletableFuture completes exceptionally, then the - * returned CompletableFuture also does so, with a - * CompletionException holding this exception as its cause. - * Similarly, if the computed CompletableFuture completes - * exceptionally, then so does the returned CompletableFuture. - * - * @param fn the function returning a new CompletableFuture - * @return the CompletableFuture - */ public <U> CompletableFuture<U> thenComposeAsync - (Function<? super T, CompletableFuture<U>> fn) { + (Function<? super T, ? extends CompletionStage<U>> fn) { return doThenCompose(fn, ForkJoinPool.commonPool()); } - /** - * Returns a CompletableFuture that upon completion, has the same - * value as that produced asynchronously using the given executor - * by the given function of this CompletableFuture. - * - * <p>If this CompletableFuture completes exceptionally, then the - * returned CompletableFuture also does so, with a - * CompletionException holding this exception as its cause. - * Similarly, if the computed CompletableFuture completes - * exceptionally, then so does the returned CompletableFuture. - * - * @param fn the function returning a new CompletableFuture - * @param executor the executor to use for asynchronous execution - * @return the CompletableFuture - */ public <U> CompletableFuture<U> thenComposeAsync - (Function<? super T, CompletableFuture<U>> fn, + (Function<? super T, ? extends CompletionStage<U>> fn, Executor executor) { if (executor == null) throw new NullPointerException(); return doThenCompose(fn, executor); } - private <U> CompletableFuture<U> doThenCompose - (Function<? super T, CompletableFuture<U>> fn, - Executor e) { - if (fn == null) throw new NullPointerException(); - CompletableFuture<U> dst = null; - ThenCompose<T,U> d = null; - Object r; - if ((r = result) == null) { - dst = new CompletableFuture<U>(); - CompletionNode p = new CompletionNode - (d = new ThenCompose<T,U>(this, fn, dst, e)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject - (this, COMPLETIONS, p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - if (ex == null) { - if (e != null) { - if (dst == null) - dst = new CompletableFuture<U>(); - e.execute(new AsyncCompose<T,U>(t, fn, dst)); - } - else { - try { - if ((dst = fn.apply(t)) == null) - ex = new NullPointerException(); - } catch (Throwable rex) { - ex = rex; - } - } - } - if (dst == null) - dst = new CompletableFuture<U>(); - if (e == null || ex != null) - dst.internalComplete(null, ex); - } - helpPostComplete(); - dst.helpPostComplete(); - return dst; + public CompletableFuture<T> whenComplete + (BiConsumer<? super T, ? super Throwable> action) { + return doWhenComplete(action, null); + } + + public CompletableFuture<T> whenCompleteAsync + (BiConsumer<? super T, ? super Throwable> action) { + return doWhenComplete(action, ForkJoinPool.commonPool()); + } + + public CompletableFuture<T> whenCompleteAsync + (BiConsumer<? super T, ? super Throwable> action, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doWhenComplete(action, executor); + } + + public <U> CompletableFuture<U> handle + (BiFunction<? super T, Throwable, ? extends U> fn) { + return doHandle(fn, null); } + public <U> CompletableFuture<U> handleAsync + (BiFunction<? super T, Throwable, ? extends U> fn) { + return doHandle(fn, ForkJoinPool.commonPool()); + } + + public <U> CompletableFuture<U> handleAsync + (BiFunction<? super T, Throwable, ? extends U> fn, + Executor executor) { + if (executor == null) throw new NullPointerException(); + return doHandle(fn, executor); + } + + /** + * Returns this CompletableFuture + * + * @return this CompletableFuture + */ + public CompletableFuture<T> toCompletableFuture() { + return this; + } + + // not in interface CompletionStage + /** * Returns a new CompletableFuture that is completed when this * CompletableFuture completes, with the result of the given @@ -2868,6 +2608,8 @@ * completion when it completes exceptionally; otherwise, if this * CompletableFuture completes normally, then the returned * CompletableFuture also completes normally with the same value. + * Note: More flexible versions of this functionality are + * available using methods {@code whenComplete} and {@code handle}. * * @param fn the function to use to compute the value of the * returned CompletableFuture if this CompletableFuture completed @@ -2882,7 +2624,8 @@ Object r; if ((r = result) == null) { CompletionNode p = - new CompletionNode(d = new ExceptionCompletion<T>(this, fn, dst)); + new CompletionNode(d = new ExceptionCompletion<T> + (this, fn, dst)); while ((r = result) == null) { if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, p.next = completions, p)) @@ -2910,59 +2653,6 @@ return dst; } - /** - * Returns a new CompletableFuture that is completed when this - * CompletableFuture completes, with the result of the given - * function of the result and exception of this CompletableFuture's - * completion. The given function is invoked with the result (or - * {@code null} if none) and the exception (or {@code null} if none) - * of this CompletableFuture when complete. - * - * @param fn the function to use to compute the value of the - * returned CompletableFuture - * @return the new CompletableFuture - */ - public <U> CompletableFuture<U> handle - (BiFunction<? super T, Throwable, ? extends U> fn) { - if (fn == null) throw new NullPointerException(); - CompletableFuture<U> dst = new CompletableFuture<U>(); - HandleCompletion<T,U> d = null; - Object r; - if ((r = result) == null) { - CompletionNode p = - new CompletionNode(d = new HandleCompletion<T,U>(this, fn, dst)); - while ((r = result) == null) { - if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, - p.next = completions, p)) - break; - } - } - if (r != null && (d == null || d.compareAndSet(0, 1))) { - T t; Throwable ex; - if (r instanceof AltResult) { - ex = ((AltResult)r).ex; - t = null; - } - else { - ex = null; - @SuppressWarnings("unchecked") T tr = (T) r; - t = tr; - } - U u; Throwable dx; - try { - u = fn.apply(t, ex); - dx = null; - } catch (Throwable rex) { - dx = rex; - u = null; - } - dst.internalComplete(u, dx); - } - helpPostComplete(); - return dst; - } - - /* ------------- Arbitrary-arity constructions -------------- */ /* @@ -3215,6 +2905,21 @@ } /** + * Returns {@code true} if this CompletableFuture completed + * exceptionally, in any way. Possible causes include + * cancellation, explicit invocation of {@code + * completeExceptionally}, and abrupt termination of a + * CompletionStage action. + * + * @return {@code true} if this CompletableFuture completed + * exceptionally + */ + public boolean isCompletedExceptionally() { + Object r; + return ((r = result) instanceof AltResult) && r != NIL; + } + + /** * Forcibly sets or resets the value subsequently returned by * method {@link #get()} and related methods, whether or not * already completed. This method is designed for use only in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/util/concurrent/CompletionStage.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,760 @@ +/* + * 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. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +package java.util.concurrent; +import java.util.function.Supplier; +import java.util.function.Consumer; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.BiFunction; +import java.util.concurrent.Executor; + +/** + * A stage of a possibly asynchronous computation, that performs an + * action or computes a value when another CompletionStage completes. + * A stage completes upon termination of its computation, but this may + * in turn trigger other dependent stages. The functionality defined + * in this interface takes only a few basic forms, which expand out to + * a larger set of methods to capture a range of usage styles: <ul> + * + * <li>The computation performed by a stage may be expressed as a + * Function, Consumer, or Runnable (using methods with names including + * <em>apply</em>, <em>accept</em>, or <em>run</em>, respectively) + * depending on whether it requires arguments and/or produces results. + * For example, {@code stage.thenApply(x -> square(x)).thenAccept(x -> + * System.out.print(x)).thenRun(() -> System.out.println())}. An + * additional form (<em>compose</em>) applies functions of stages + * themselves, rather than their results. </li> + * + * <li> One stage's execution may be triggered by completion of a + * single stage, or both of two stages, or either of two stages. + * Dependencies on a single stage are arranged using methods with + * prefix <em>then</em>. Those triggered by completion of + * <em>both</em> of two stages may <em>combine</em> their results or + * effects, using correspondingly named methods. Those triggered by + * <em>either</em> of two stages make no guarantees about which of the + * results or effects are used for the dependent stage's + * computation.</li> + * + * <li> Dependencies among stages control the triggering of + * computations, but do not otherwise guarantee any particular + * ordering. Additionally, execution of a new stage's computations may + * be arranged in any of three ways: default execution, default + * asynchronous execution (using methods with suffix <em>async</em> + * that employ the stage's default asynchronous execution facility), + * or custom (via a supplied {@link Executor}). The execution + * properties of default and async modes are specified by + * CompletionStage implementations, not this interface. Methods with + * explicit Executor arguments may have arbitrary execution + * properties, and might not even support concurrent execution, but + * are arranged for processing in a way that accommodates asynchrony. + * + * <li> Two method forms support processing whether the triggering + * stage completed normally or exceptionally: Method {@link + * #whenComplete whenComplete} allows injection of an action + * regardless of outcome, otherwise preserving the outcome in its + * completion. Method {@link #handle handle} additionally allows the + * stage to compute a replacement result that may enable further + * processing by other dependent stages. In all other cases, if a + * stage's computation terminates abruptly with an (unchecked) + * exception or error, then all dependent stages requiring its + * completion complete exceptionally as well, with a {@link + * CompletionException} holding the exception as its cause. If a + * stage is dependent on <em>both</em> of two stages, and both + * complete exceptionally, then the CompletionException may correspond + * to either one of these exceptions. If a stage is dependent on + * <em>either</em> of two others, and only one of them completes + * exceptionally, no guarantees are made about whether the dependent + * stage completes normally or exceptionally. In the case of method + * {@code whenComplete}, when the supplied action itself encounters an + * exception, then the stage exceptionally completes with this + * exception if not already completed exceptionally.</li> + * + * </ul> + * + * <p>All methods adhere to the above triggering, execution, and + * exceptional completion specifications (which are not repeated in + * individual method specifications). Additionally, while arguments + * used to pass a completion result (that is, for parameters of type + * {@code T}) for methods accepting them may be null, passing a null + * value for any other parameter will result in a {@link + * NullPointerException} being thrown. + * + * <p>This interface does not define methods for initially creating, + * forcibly completing normally or exceptionally, probing completion + * status or results, or awaiting completion of a stage. + * Implementations of CompletionStage may provide means of achieving + * such effects, as appropriate. Method {@link #toCompletableFuture} + * enables interoperability among different implementations of this + * interface by providing a common conversion type. + * + * @author Doug Lea + * @since 1.8 + */ +public interface CompletionStage<T> { + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed with this stage's result as the argument + * to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using this stage's default asynchronous + * execution facility, with this stage's result as the argument to + * the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> thenApplyAsync + (Function<? super T,? extends U> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using the supplied Executor, with this + * stage's result as the argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> thenApplyAsync + (Function<? super T,? extends U> fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed with this stage's result as the argument + * to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> thenAccept(Consumer<? super T> action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using this stage's default asynchronous + * execution facility, with this stage's result as the argument to + * the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using the supplied Executor, with this + * stage's result as the argument to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, + Executor executor); + /** + * Returns a new CompletionStage that, when this stage completes + * normally, executes the given action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> thenRun(Runnable action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, executes the given action using this stage's default + * asynchronous execution facility. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> thenRunAsync(Runnable action); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, executes the given action using the supplied Executor. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage<Void> thenRunAsync(Runnable action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage both complete normally, is executed with the two + * results as arguments to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param <U> the type of the other CompletionStage's result + * @param <V> the function's return type + * @return the new CompletionStage + */ + public <U,V> CompletionStage<V> thenCombine + (CompletionStage<? extends U> other, + BiFunction<? super T,? super U,? extends V> fn); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using this stage's + * default asynchronous execution facility, with the two results + * as arguments to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param <U> the type of the other CompletionStage's result + * @param <V> the function's return type + * @return the new CompletionStage + */ + public <U,V> CompletionStage<V> thenCombineAsync + (CompletionStage<? extends U> other, + BiFunction<? super T,? super U,? extends V> fn); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using the supplied + * executor, with the two results as arguments to the supplied + * function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param <U> the type of the other CompletionStage's result + * @param <V> the function's return type + * @return the new CompletionStage + */ + public <U,V> CompletionStage<V> thenCombineAsync + (CompletionStage<? extends U> other, + BiFunction<? super T,? super U,? extends V> fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage both complete normally, is executed with the two + * results as arguments to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param <U> the type of the other CompletionStage's result + * @return the new CompletionStage + */ + public <U> CompletionStage<Void> thenAcceptBoth + (CompletionStage<? extends U> other, + BiConsumer<? super T, ? super U> action); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using this stage's + * default asynchronous execution facility, with the two results + * as arguments to the supplied action. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param <U> the type of the other CompletionStage's result + * @return the new CompletionStage + */ + public <U> CompletionStage<Void> thenAcceptBothAsync + (CompletionStage<? extends U> other, + BiConsumer<? super T, ? super U> action); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, is executed using the supplied + * executor, with the two results as arguments to the supplied + * function. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param <U> the type of the other CompletionStage's result + * @return the new CompletionStage + */ + public <U> CompletionStage<Void> thenAcceptBothAsync + (CompletionStage<? extends U> other, + BiConsumer<? super T, ? super U> action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage both complete normally, executes the given action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, + Runnable action); + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, executes the given action using + * this stage's default asynchronous execution facility. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, + Runnable action); + + /** + * Returns a new CompletionStage that, when this and the other + * given stage complete normally, executes the given action using + * the supplied executor + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, + Runnable action, + Executor executor); + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed with the + * corresponding result as argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> applyToEither + (CompletionStage<? extends T> other, + Function<? super T, U> fn); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using this + * stage's default asynchronous execution facility, with the + * corresponding result as argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> applyToEitherAsync + (CompletionStage<? extends T> other, + Function<? super T, U> fn); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using the + * supplied executor, with the corresponding result as argument to + * the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param fn the function to use to compute the value of + * the returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> applyToEitherAsync + (CompletionStage<? extends T> other, + Function<? super T, U> fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed with the + * corresponding result as argument to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> acceptEither + (CompletionStage<? extends T> other, + Consumer<? super T> action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using this + * stage's default asynchronous execution facility, with the + * corresponding result as argument to the supplied action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> acceptEitherAsync + (CompletionStage<? extends T> other, + Consumer<? super T> action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, is executed using the + * supplied executor, with the corresponding result as argument to + * the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage<Void> acceptEitherAsync + (CompletionStage<? extends T> other, + Consumer<? super T> action, + Executor executor); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, executes the given action. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> runAfterEither(CompletionStage<?> other, + Runnable action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, executes the given action + * using this stage's default asynchronous execution facility. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @return the new CompletionStage + */ + public CompletionStage<Void> runAfterEitherAsync + (CompletionStage<?> other, + Runnable action); + + /** + * Returns a new CompletionStage that, when either this or the + * other given stage complete normally, executes the given action + * using supplied executor. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param other the other CompletionStage + * @param action the action to perform before completing the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage<Void> runAfterEitherAsync + (CompletionStage<?> other, + Runnable action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed with this stage as the argument + * to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function returning a new CompletionStage + * @param <U> the type of the returned CompletionStage's result + * @return the CompletionStage + */ + public <U> CompletionStage<U> thenCompose + (Function<? super T, ? extends CompletionStage<U>> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using this stage's default asynchronous + * execution facility, with this stage as the argument to the + * supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function returning a new CompletionStage + * @param <U> the type of the returned CompletionStage's result + * @return the CompletionStage + */ + public <U> CompletionStage<U> thenComposeAsync + (Function<? super T, ? extends CompletionStage<U>> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * normally, is executed using the supplied Executor, with this + * stage's result as the argument to the supplied function. + * + * See the {@link CompletionStage} documentation for rules + * covering exceptional completion. + * + * @param fn the function returning a new CompletionStage + * @param executor the executor to use for asynchronous execution + * @param <U> the type of the returned CompletionStage's result + * @return the CompletionStage + */ + public <U> CompletionStage<U> thenComposeAsync + (Function<? super T, ? extends CompletionStage<U>> fn, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * exceptionally, is executed with this stage's exception as the + * argument to the supplied function. Otherwise, if this stage + * completes normally, then the returned stage also completes + * normally with the same value. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage if this CompletionStage completed + * exceptionally + * @return the new CompletionStage + */ + public CompletionStage<T> exceptionally + (Function<Throwable, ? extends T> fn); + + /** + * Returns a new CompletionStage with the same result or exception + * as this stage, and when this stage completes, executes the + * given action with the result (or {@code null} if none) and the + * exception (or {@code null} if none) of this stage. + * + * @param action the action to perform + * @return the new CompletionStage + */ + public CompletionStage<T> whenComplete + (BiConsumer<? super T, ? super Throwable> action); + + /** + * Returns a new CompletionStage with the same result or exception + * as this stage, and when this stage completes, executes the + * given action executes the given action using this stage's + * default asynchronous execution facility, with the result (or + * {@code null} if none) and the exception (or {@code null} if + * none) of this stage as arguments. + * + * @param action the action to perform + * @return the new CompletionStage + */ + public CompletionStage<T> whenCompleteAsync + (BiConsumer<? super T, ? super Throwable> action); + + /** + * Returns a new CompletionStage with the same result or exception + * as this stage, and when this stage completes, executes using + * the supplied Executor, the given action with the result (or + * {@code null} if none) and the exception (or {@code null} if + * none) of this stage as arguments. + * + * @param action the action to perform + * @param executor the executor to use for asynchronous execution + * @return the new CompletionStage + */ + public CompletionStage<T> whenCompleteAsync + (BiConsumer<? super T, ? super Throwable> action, + Executor executor); + + /** + * Returns a new CompletionStage that, when this stage completes + * either normally or exceptionally, is executed with this stage's + * result and exception as arguments to the supplied function. + * The given function is invoked with the result (or {@code null} + * if none) and the exception (or {@code null} if none) of this + * stage when complete as arguments. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> handle + (BiFunction<? super T, Throwable, ? extends U> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * either normally or exceptionally, is executed using this stage's + * default asynchronous execution facility, with this stage's + * result and exception as arguments to the supplied function. + * The given function is invoked with the result (or {@code null} + * if none) and the exception (or {@code null} if none) of this + * stage when complete as arguments. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> handleAsync + (BiFunction<? super T, Throwable, ? extends U> fn); + + /** + * Returns a new CompletionStage that, when this stage completes + * either normally or exceptionally, is executed using the + * supplied executor, with this stage's result and exception as + * arguments to the supplied function. The given function is + * invoked with the result (or {@code null} if none) and the + * exception (or {@code null} if none) of this stage when complete + * as arguments. + * + * @param fn the function to use to compute the value of the + * returned CompletionStage + * @param executor the executor to use for asynchronous execution + * @param <U> the function's return type + * @return the new CompletionStage + */ + public <U> CompletionStage<U> handleAsync + (BiFunction<? super T, Throwable, ? extends U> fn, + Executor executor); + + /** + * Returns a {@link CompletableFuture} maintaining the same + * completion properties as this stage. If this stage is already a + * CompletableFuture, this method may return this stage itself. + * Otherwise, invocation of this method may be equivalent in + * effect to {@code thenApply(x -> x)}, but returning an instance + * of type {@code CompletableFuture}. A CompletionStage + * implementation that does not choose to interoperate with others + * may throw {@code UnsupportedOperationException}. + * + * @return the CompletableFuture + * @throws UnsupportedOperationException if this implementation + * does not interoperate with CompletableFuture + */ + public CompletableFuture<T> toCompletableFuture(); + +}
--- a/src/share/classes/java/util/logging/XMLFormatter.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/logging/XMLFormatter.java Wed Aug 07 19:56:20 2013 -0700 @@ -47,7 +47,7 @@ private LogManager manager = LogManager.getLogManager(); // Append a two digit number. - private void a2(StringBuffer sb, int x) { + private void a2(StringBuilder sb, int x) { if (x < 10) { sb.append('0'); } @@ -55,25 +55,26 @@ } // Append the time and date in ISO 8601 format - private void appendISO8601(StringBuffer sb, long millis) { - Date date = new Date(millis); - sb.append(date.getYear() + 1900); + private void appendISO8601(StringBuilder sb, long millis) { + GregorianCalendar cal = new GregorianCalendar(); + cal.setTimeInMillis(millis); + sb.append(cal.get(Calendar.YEAR) + 1900); sb.append('-'); - a2(sb, date.getMonth() + 1); + a2(sb, cal.get(Calendar.MONTH) + 1); sb.append('-'); - a2(sb, date.getDate()); + a2(sb, cal.get(Calendar.DAY_OF_MONTH)); sb.append('T'); - a2(sb, date.getHours()); + a2(sb, cal.get(Calendar.HOUR_OF_DAY)); sb.append(':'); - a2(sb, date.getMinutes()); + a2(sb, cal.get(Calendar.MINUTE)); sb.append(':'); - a2(sb, date.getSeconds()); + a2(sb, cal.get(Calendar.SECOND)); } - // Append to the given StringBuffer an escaped version of the + // Append to the given StringBuilder an escaped version of the // given text string where XML special characters have been escaped. // For a null string we append "<null>" - private void escape(StringBuffer sb, String text) { + private void escape(StringBuilder sb, String text) { if (text == null) { text = "<null>"; } @@ -102,7 +103,7 @@ * @return a formatted log record */ public String format(LogRecord record) { - StringBuffer sb = new StringBuffer(500); + StringBuilder sb = new StringBuilder(500); sb.append("<record>\n"); sb.append(" <date>"); @@ -224,7 +225,7 @@ * @return a valid XML string */ public String getHead(Handler h) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); String encoding; sb.append("<?xml version=\"1.0\"");
--- a/src/share/classes/java/util/stream/AbstractPipeline.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/AbstractPipeline.java Wed Aug 07 19:56:20 2013 -0700 @@ -75,11 +75,13 @@ * Backlink to the head of the pipeline chain (self if this is the source * stage). */ + @SuppressWarnings("rawtypes") private final AbstractPipeline sourceStage; /** * The "upstream" pipeline, or null if this is the source stage. */ + @SuppressWarnings("rawtypes") private final AbstractPipeline previousStage; /** @@ -92,6 +94,7 @@ * The next stage in the pipeline, or null if this is the last stage. * Effectively final at the point of linking to the next pipeline. */ + @SuppressWarnings("rawtypes") private AbstractPipeline nextStage; /** @@ -222,8 +225,8 @@ linkedOrConsumed = true; return isParallel() - ? (R) terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags())) - : (R) terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags())); + ? terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags())) + : terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags())); } /** @@ -232,6 +235,7 @@ * @param generator the array generator to be used to create array instances * @return a flat array-backed Node that holds the collected output elements */ + @SuppressWarnings("unchecked") final Node<E_OUT> evaluateToArrayNode(IntFunction<E_OUT[]> generator) { if (linkedOrConsumed) throw new IllegalStateException("stream has already been operated upon"); @@ -256,6 +260,7 @@ * @throws IllegalStateException if this pipeline stage is not the source * stage. */ + @SuppressWarnings("unchecked") final Spliterator<E_OUT> sourceStageSpliterator() { if (this != sourceStage) throw new IllegalStateException(); @@ -265,11 +270,13 @@ linkedOrConsumed = true; if (sourceStage.sourceSpliterator != null) { + @SuppressWarnings("unchecked") Spliterator<E_OUT> s = sourceStage.sourceSpliterator; sourceStage.sourceSpliterator = null; return s; } else if (sourceStage.sourceSupplier != null) { + @SuppressWarnings("unchecked") Spliterator<E_OUT> s = (Spliterator<E_OUT>) sourceStage.sourceSupplier.get(); sourceStage.sourceSupplier = null; return s; @@ -282,12 +289,14 @@ // BaseStream @Override + @SuppressWarnings("unchecked") public final S sequential() { sourceStage.parallel = false; return (S) this; } @Override + @SuppressWarnings("unchecked") public final S parallel() { sourceStage.parallel = true; return (S) this; @@ -295,6 +304,7 @@ // Primitive specialization use co-variant overrides, hence is not final @Override + @SuppressWarnings("unchecked") public Spliterator<E_OUT> spliterator() { if (linkedOrConsumed) throw new IllegalStateException("stream has already been operated upon"); @@ -302,12 +312,14 @@ if (this == sourceStage) { if (sourceStage.sourceSpliterator != null) { - Spliterator<E_OUT> s = sourceStage.sourceSpliterator; + @SuppressWarnings("unchecked") + Spliterator<E_OUT> s = (Spliterator<E_OUT>) sourceStage.sourceSpliterator; sourceStage.sourceSpliterator = null; return s; } else if (sourceStage.sourceSupplier != null) { - Supplier<Spliterator<E_OUT>> s = sourceStage.sourceSupplier; + @SuppressWarnings("unchecked") + Supplier<Spliterator<E_OUT>> s = (Supplier<Spliterator<E_OUT>>) sourceStage.sourceSupplier; sourceStage.sourceSupplier = null; return lazySpliterator(s); } @@ -349,10 +361,11 @@ * @param terminalFlags Operation flags for the terminal operation */ private void parallelPrepare(int terminalFlags) { + @SuppressWarnings("rawtypes") AbstractPipeline backPropagationHead = sourceStage; if (sourceStage.sourceAnyStateful) { int depth = 1; - for (AbstractPipeline u = sourceStage, p = sourceStage.nextStage; + for ( @SuppressWarnings("rawtypes") AbstractPipeline u = sourceStage, p = sourceStage.nextStage; p != null; u = p, p = p.nextStage) { int thisOpFlags = p.sourceOrOpFlags; @@ -383,7 +396,7 @@ // Apply the upstream terminal flags if (terminalFlags != 0) { int upstreamTerminalFlags = terminalFlags & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK; - for (AbstractPipeline p = backPropagationHead; p.nextStage != null; p = p.nextStage) { + for ( @SuppressWarnings("rawtypes") AbstractPipeline p = backPropagationHead; p.nextStage != null; p = p.nextStage) { p.combinedFlags = StreamOpFlag.combineOpFlags(upstreamTerminalFlags, p.combinedFlags); } @@ -398,6 +411,7 @@ * of all computations up to and including the most recent stateful * operation. */ + @SuppressWarnings("unchecked") private Spliterator<?> sourceSpliterator(int terminalFlags) { // Get the source spliterator of the pipeline Spliterator<?> spliterator = null; @@ -421,7 +435,7 @@ // Adapt the source spliterator, evaluating each stateful op // in the pipeline up to and including this pipeline stage - for (AbstractPipeline u = sourceStage, p = sourceStage.nextStage, e = this; + for ( @SuppressWarnings("rawtypes") AbstractPipeline u = sourceStage, p = sourceStage.nextStage, e = this; u != e; u = p, p = p.nextStage) { @@ -442,6 +456,7 @@ @Override final StreamShape getSourceShape() { + @SuppressWarnings("rawtypes") AbstractPipeline p = AbstractPipeline.this; while (p.depth > 0) { p = p.previousStage; @@ -475,7 +490,9 @@ } @Override + @SuppressWarnings("unchecked") final <P_IN> void copyIntoWithCancel(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator) { + @SuppressWarnings({"rawtypes","unchecked"}) AbstractPipeline p = AbstractPipeline.this; while (p.depth > 0) { p = p.previousStage; @@ -495,16 +512,18 @@ } @Override + @SuppressWarnings("unchecked") final <P_IN> Sink<P_IN> wrapSink(Sink<E_OUT> sink) { Objects.requireNonNull(sink); - for (AbstractPipeline p=AbstractPipeline.this; p.depth > 0; p=p.previousStage) { + for ( @SuppressWarnings("rawtypes") AbstractPipeline p=AbstractPipeline.this; p.depth > 0; p=p.previousStage) { sink = p.opWrapSink(p.previousStage.combinedFlags, sink); } return (Sink<P_IN>) sink; } @Override + @SuppressWarnings("unchecked") final <P_IN> Spliterator<E_OUT> wrapSpliterator(Spliterator<P_IN> sourceSpliterator) { if (depth == 0) { return (Spliterator<E_OUT>) sourceSpliterator; @@ -591,16 +610,19 @@ /** * Make a node builder compatible with this stream shape. * - * @param exactSizeIfKnown if {@literal >=0}, then a node builder will be created that - * has a fixed capacity of at most sizeIfKnown elements. If {@literal < 0}, - * then the node builder has an unfixed capacity. A fixed capacity node - * builder will throw exceptions if an element is added after builder has - * reached capacity, or is built before the builder has reached capacity. + * @param exactSizeIfKnown if {@literal >=0}, then a node builder will be + * created that has a fixed capacity of at most sizeIfKnown elements. If + * {@literal < 0}, then the node builder has an unfixed capacity. A fixed + * capacity node builder will throw exceptions if an element is added after + * builder has reached capacity, or is built before the builder has reached + * capacity. + * * @param generator the array generator to be used to create instances of a * T[] array. For implementations supporting primitive nodes, this parameter * may be ignored. * @return a node builder */ + @Override abstract Node.Builder<E_OUT> makeNodeBuilder(long exactSizeIfKnown, IntFunction<E_OUT[]> generator); @@ -679,6 +701,7 @@ * @param spliterator the source {@code Spliterator} * @return a {@code Spliterator} describing the result of the evaluation */ + @SuppressWarnings("unchecked") <P_IN> Spliterator<E_OUT> opEvaluateParallelLazy(PipelineHelper<E_OUT> helper, Spliterator<P_IN> spliterator) { return opEvaluateParallel(helper, spliterator, i -> (E_OUT[]) new Object[i]).spliterator();
--- a/src/share/classes/java/util/stream/AbstractShortCircuitTask.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/AbstractShortCircuitTask.java Wed Aug 07 19:56:20 2013 -0700 @@ -39,6 +39,7 @@ * @param <K> type of child and sibling tasks * @since 1.8 */ +@SuppressWarnings("serial") abstract class AbstractShortCircuitTask<P_IN, P_OUT, R, K extends AbstractShortCircuitTask<P_IN, P_OUT, R, K>> extends AbstractTask<P_IN, P_OUT, R, K> { @@ -219,7 +220,8 @@ */ protected void cancelLaterNodes() { // Go up the tree, cancel right siblings of this node and all parents - for (K parent = getParent(), node = (K) this; parent != null; + for (@SuppressWarnings("unchecked") K parent = getParent(), node = (K) this; + parent != null; node = parent, parent = parent.getParent()) { // If node is a left child of parent, then has a right sibling if (parent.leftChild == node) {
--- a/src/share/classes/java/util/stream/AbstractTask.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/AbstractTask.java Wed Aug 07 19:56:20 2013 -0700 @@ -73,6 +73,9 @@ * } * }</pre> * + * <p>Serialization is not supported as there is no intention to serialize + * tasks managed by stream ops. + * * @param <P_IN> Type of elements input to the pipeline * @param <P_OUT> Type of elements output from the pipeline * @param <R> Type of intermediate result, which may be different from operation @@ -80,6 +83,7 @@ * @param <K> Type of parent, child and sibling tasks * @since 1.8 */ +@SuppressWarnings("serial") abstract class AbstractTask<P_IN, P_OUT, R, K extends AbstractTask<P_IN, P_OUT, R, K>> extends CountedCompleter<R> {
--- a/src/share/classes/java/util/stream/Collector.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/Collector.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,40 +25,45 @@ package java.util.stream; import java.util.Collections; +import java.util.EnumSet; import java.util.Set; -import java.util.function.BiFunction; +import java.util.function.BiConsumer; import java.util.function.BinaryOperator; +import java.util.function.Function; import java.util.function.Supplier; /** * A <a href="package-summary.html#Reduction">reduction operation</a> that - * supports folding input elements into a cumulative result. The result may be - * a value or may be a mutable result container. Examples of operations - * accumulating results into a mutable result container include: accumulating - * input elements into a {@code Collection}; concatenating strings into a - * {@code StringBuilder}; computing summary information about elements such as - * sum, min, max, or average; computing "pivot table" summaries such as "maximum - * valued transaction by seller", etc. Reduction operations can be performed - * either sequentially or in parallel. + * folds input elements into a mutable result container, optionally transforming + * the accumulated result into a final representation after all input elements + * have been processed. + * + * <p>Examples of mutable reduction operations include: + * accumulating elements into a {@code Collection}; concatenating + * strings using a {@code StringBuilder}; computing summary information about + * elements such as sum, min, max, or average; computing "pivot table" summaries + * such as "maximum valued transaction by seller", etc. Reduction operations + * can be performed either sequentially or in parallel. * * <p>The following are examples of using the predefined {@code Collector} * implementations in {@link Collectors} with the {@code Stream} API to perform * mutable reduction tasks: * <pre>{@code - * // Accumulate elements into a List - * List<String> list = stream.collect(Collectors.toList()); + * // Accumulate names into a List + * List<String> list = people.stream().map(Person::getName).collect(Collectors.toList()); * - * // Accumulate elements into a TreeSet - * Set<String> list = stream.collect(Collectors.toCollection(TreeSet::new)); + * // Accumulate names into a TreeSet + * Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new)); * * // Convert elements to strings and concatenate them, separated by commas - * String joined = stream.map(Object::toString) - * .collect(Collectors.toStringJoiner(", ")) - * .toString(); + * String joined = things.stream() + * .map(Object::toString) + * .collect(Collectors.joining(", ")); * * // Find highest-paid employee * Employee highestPaid = employees.stream() - * .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary))); + * .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary))) + * .get(); * * // Group employees by department * Map<Department, List<Employee>> byDept @@ -66,7 +71,7 @@ * .collect(Collectors.groupingBy(Employee::getDepartment)); * * // Find highest-paid employee by department - * Map<Department, Employee> highestPaidByDept + * Map<Department, Optional<Employee>> highestPaidByDept * = employees.stream() * .collect(Collectors.groupingBy(Employee::getDepartment, * Collectors.maxBy(Comparators.comparing(Employee::getSalary)))); @@ -74,43 +79,42 @@ * // Partition students into passing and failing * Map<Boolean, List<Student>> passingFailing = * students.stream() - * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD); + * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD)); * * }</pre> * - * <p>A {@code Collector} is specified by three functions that work together to - * manage a result or result container. They are: creation of an initial - * result, incorporating a new data element into a result, and combining two - * results into one. The last function -- combining two results into one -- is - * used during parallel operations, where subsets of the input are accumulated - * in parallel, and then the subresults merged into a combined result. The - * result may be a mutable container or a value. If the result is mutable, the - * accumulation and combination functions may either mutate their left argument - * and return that (such as adding elements to a collection), or return a new - * result, in which case it should not perform any mutation. + * <p>A {@code Collector} is specified by four functions that work together to + * accumulate entries into a mutable result container, and optionally perform + * a final transform on the result. They are: creation of a new result container, + * incorporating a new data element into a result container, combining two + * result containers into one, and performing a final transform on the container. + * The combiner function is used during parallel operations, where + * subsets of the input are accumulated into separate result + * containers, and then the subresults merged into a combined result. The + * combiner function may merge one set of subresults into the other and return + * that, or it may return a new object to describe the combined results. * - * <p>Collectors also have a set of characteristics, including - * {@link Characteristics#CONCURRENT} and - * {@link Characteristics#STRICTLY_MUTATIVE}. These characteristics provide + * <p>Collectors also have a set of characteristics, such as + * {@link Characteristics#CONCURRENT}. These characteristics provide * hints that can be used by a reduction implementation to provide better * performance. * * <p>Libraries that implement reduction based on {@code Collector}, such as * {@link Stream#collect(Collector)}, must adhere to the following constraints: * <ul> - * <li>The first argument passed to the accumulator function, and both - * arguments passed to the combiner function, must be the result of a - * previous invocation of {@link #resultSupplier()}, {@link #accumulator()}, - * or {@link #combiner()}.</li> + * <li>The first argument passed to the accumulator function, both + * arguments passed to the combiner function, and the argument passed to the + * finisher function must be the result of a previous invocation of the + * result supplier, accumulator, or combiner functions.</li> * <li>The implementation should not do anything with the result of any of * the result supplier, accumulator, or combiner functions other than to - * pass them again to the accumulator or combiner functions, or return them - * to the caller of the reduction operation.</li> - * <li>If a result is passed to the accumulator or combiner function, and - * the same object is not returned from that function, it is never used - * again.</li> - * <li>Once a result is passed to the combiner function, it is never passed - * to the accumulator function again.</li> + * pass them again to the accumulator, combiner, or finisher functions, + * or return them to the caller of the reduction operation.</li> + * <li>If a result is passed to the combiner or finisher + * function, and the same object is not returned from that function, it is + * never used again.</li> + * <li>Once a result is passed to the combiner or finisher function, it + * is never passed to the accumulator function again.</li> * <li>For non-concurrent collectors, any result returned from the result * supplier, accumulator, or combiner functions must be serially * thread-confined. This enables collection to occur in parallel without @@ -132,11 +136,10 @@ * Performing a reduction operation with a {@code Collector} should produce a * result equivalent to: * <pre>{@code - * BiFunction<R,T,R> accumulator = collector.accumulator(); - * R result = collector.resultSupplier().get(); + * R container = collector.supplier().get(); * for (T t : data) - * result = accumulator.apply(result, t); - * return result; + * collector.accumulator().accept(container, t); + * return collector.finisher().apply(container); * }</pre> * * <p>However, the library is free to partition the input, perform the reduction @@ -149,7 +152,7 @@ * is accumulating elements into a {@code TreeSet}. In this case, the {@code * resultSupplier()} function is {@code () -> new Treeset<T>()}, the * {@code accumulator} function is - * {@code (set, element) -> { set.add(element); return set; }}, and the combiner + * {@code (set, element) -> set.add(element) }, and the combiner * function is {@code (left, right) -> { left.addAll(right); return left; }}. * (This behavior is implemented by * {@code Collectors.toCollection(TreeSet::new)}). @@ -159,51 +162,49 @@ * @see Stream#collect(Collector) * @see Collectors * - * @param <T> the type of input element to the collect operation - * @param <R> the result type of the collect operation + * @param <T> the type of input elements to the reduction operation + * @param <A> the mutable accumulation type of the reduction operation (often + * hidden as an implementation detail) + * @param <R> the result type of the reduction operation * @since 1.8 */ -public interface Collector<T, R> { +public interface Collector<T, A, R> { /** - * A function that creates and returns a new result that represents - * "no values". If the accumulator or combiner functions may mutate their - * arguments, this must be a new, empty result container. + * A function that creates and returns a new mutable result container. * - * @return a function which, when invoked, returns a result representing - * "no values" + * @return a function which returns a new, mutable result container */ - Supplier<R> resultSupplier(); + Supplier<A> supplier(); /** - * A function that folds a new value into a cumulative result. The result - * may be a mutable result container or a value. The accumulator function - * may modify a mutable container and return it, or create a new result and - * return that, but if it returns a new result object, it must not modify - * any of its arguments. + * A function that folds a new value into a mutable result container. * - * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE} - * characteristic, then the accumulator function <em>must</em> always return - * its first argument, after possibly mutating its state. - * - * @return a function which folds a new value into a cumulative result + * @return a function which folds a new value into a mutable result container */ - BiFunction<R, T, R> accumulator(); + BiConsumer<A, T> accumulator(); /** * A function that accepts two partial results and merges them. The * combiner function may fold state from one argument into the other and - * return that, or may return a new result object, but if it returns - * a new result object, it must not modify the state of either of its - * arguments. - * - * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE} - * characteristic, then the combiner function <em>must</em> always return - * its first argument, after possibly mutating its state. + * return that, or may return a new result object. * * @return a function which combines two partial results into a cumulative * result */ - BinaryOperator<R> combiner(); + BinaryOperator<A> combiner(); + + /** + * Perform the final transformation from the intermediate accumulation type + * {@code A} to the final result representation {@code R}. + * + * <p>If the characteristic {@code IDENTITY_TRANSFORM} is + * set, this function may be presumed to be an identity transform with an + * unchecked cast from {@code A} to {@code R}. + * + * @return a function which transforms the intermediate result to the final + * result + */ + Function<A, R> finisher(); /** * Returns a {@code Set} of {@code Collector.Characteristics} indicating @@ -214,6 +215,62 @@ Set<Characteristics> characteristics(); /** + * Returns a new {@code Collector} described by the given {@code supplier}, + * {@code accumulator}, and {@code combiner} functions. The resulting + * {@code Collector} has the {@code Collector.Characteristics.IDENTITY_FINISH} + * characteristic. + * + * @param supplier The supplier function for the new collector + * @param accumulator The accumulator function for the new collector + * @param combiner The combiner function for the new collector + * @param characteristics The collector characteristics for the new + * collector + * @param <T> The type of input elements for the new collector + * @param <R> The type of intermediate accumulation result, and final result, + * for the new collector + * @return the new {@code Collector} + */ + public static<T, R> Collector<T, R, R> of(Supplier<R> supplier, + BiConsumer<R, T> accumulator, + BinaryOperator<R> combiner, + Characteristics... characteristics) { + Set<Characteristics> cs = (characteristics.length == 0) + ? Collectors.CH_ID + : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH, + characteristics)); + return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs); + } + + /** + * Returns a new {@code Collector} described by the given {@code supplier}, + * {@code accumulator}, {@code combiner}, and {@code finisher} functions. + * + * @param supplier The supplier function for the new collector + * @param accumulator The accumulator function for the new collector + * @param combiner The combiner function for the new collector + * @param finisher The finisher function for the new collector + * @param characteristics The collector characteristics for the new + * collector + * @param <T> The type of input elements for the new collector + * @param <A> The intermediate accumulation type of the new collector + * @param <R> The final result type of the new collector + * @return the new {@code Collector} + */ + public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier, + BiConsumer<A, T> accumulator, + BinaryOperator<A> combiner, + Function<A, R> finisher, + Characteristics... characteristics) { + Set<Characteristics> cs = Collectors.CH_NOID; + if (characteristics.length > 0) { + cs = EnumSet.noneOf(Characteristics.class); + Collections.addAll(cs, characteristics); + cs = Collections.unmodifiableSet(cs); + } + return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs); + } + + /** * Characteristics indicating properties of a {@code Collector}, which can * be used to optimize reduction implementations. */ @@ -222,8 +279,7 @@ * Indicates that this collector is <em>concurrent</em>, meaning that * the result container can support the accumulator function being * called concurrently with the same result container from multiple - * threads. Concurrent collectors must also always have the - * {@code STRICTLY_MUTATIVE} characteristic. + * threads. * * <p>If a {@code CONCURRENT} collector is not also {@code UNORDERED}, * then it should only be evaluated concurrently if applied to an @@ -238,12 +294,10 @@ UNORDERED, /** - * Indicates that this collector operates by strict mutation of its - * result container. This means that the {@link #accumulator()} and - * {@link #combiner()} functions will always modify the state of and - * return their first argument, rather than returning a different result - * container. + * Indicates that the finisher function is the identity function and + * can be elided. If set, it must be the case that an unchecked cast + * from A to R will succeed. */ - STRICTLY_MUTATIVE + IDENTITY_FINISH } }
--- a/src/share/classes/java/util/stream/Collectors.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/Collectors.java Wed Aug 07 19:56:20 2013 -0700 @@ -27,6 +27,7 @@ import java.util.AbstractMap; import java.util.AbstractSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -39,14 +40,16 @@ import java.util.List; import java.util.LongSummaryStatistics; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.StringJoiner; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.BinaryOperator; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; @@ -64,20 +67,21 @@ * mutable reduction tasks: * * <pre>{@code - * // Accumulate elements into a List - * List<Person> list = people.collect(Collectors.toList()); + * // Accumulate names into a List + * List<String> list = people.stream().map(Person::getName).collect(Collectors.toList()); * - * // Accumulate elements into a TreeSet - * List<Person> list = people.collect(Collectors.toCollection(TreeSet::new)); + * // Accumulate names into a TreeSet + * Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new)); * * // Convert elements to strings and concatenate them, separated by commas - * String joined = stream.map(Object::toString) - * .collect(Collectors.toStringJoiner(", ")) - * .toString(); + * String joined = things.stream() + * .map(Object::toString) + * .collect(Collectors.joining(", ")); * * // Find highest-paid employee * Employee highestPaid = employees.stream() - * .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary))); + * .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary))) + * .get(); * * // Group employees by department * Map<Department, List<Employee>> byDept @@ -85,7 +89,7 @@ * .collect(Collectors.groupingBy(Employee::getDepartment)); * * // Find highest-paid employee by department - * Map<Department, Employee> highestPaidByDept + * Map<Department, Optional<Employee>> highestPaidByDept * = employees.stream() * .collect(Collectors.groupingBy(Employee::getDepartment, * Collectors.maxBy(Comparator.comparing(Employee::getSalary)))); @@ -93,7 +97,7 @@ * // Partition students into passing and failing * Map<Boolean, List<Student>> passingFailing = * students.stream() - * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD); + * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD)); * * }</pre> * @@ -103,15 +107,19 @@ */ public final class Collectors { - private static final Set<Collector.Characteristics> CH_CONCURRENT + static final Set<Collector.Characteristics> CH_CONCURRENT_ID = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT, - Collector.Characteristics.STRICTLY_MUTATIVE, + Collector.Characteristics.UNORDERED, + Collector.Characteristics.IDENTITY_FINISH)); + static final Set<Collector.Characteristics> CH_CONCURRENT_NOID + = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT, Collector.Characteristics.UNORDERED)); - private static final Set<Collector.Characteristics> CH_STRICT - = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE)); - private static final Set<Collector.Characteristics> CH_STRICT_UNORDERED - = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE, - Collector.Characteristics.UNORDERED)); + static final Set<Collector.Characteristics> CH_ID + = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH)); + static final Set<Collector.Characteristics> CH_UNORDERED_ID + = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED, + Collector.Characteristics.IDENTITY_FINISH)); + static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet(); private Collectors() { } @@ -124,88 +132,64 @@ * * @param <T> the type of input arguments to the merge function * @return a merge function which always throw {@code IllegalStateException} - * - * @see #firstWinsMerger() - * @see #lastWinsMerger() */ - public static <T> BinaryOperator<T> throwingMerger() { + private static <T> BinaryOperator<T> throwingMerger() { return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }; } /** - * Returns a merge function, suitable for use in - * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or - * {@link #toMap(Function, Function, BinaryOperator) toMap()}, - * which implements a "first wins" policy. - * - * @param <T> the type of input arguments to the merge function - * @return a merge function which always returns its first argument - * @see #lastWinsMerger() - * @see #throwingMerger() - */ - public static <T> BinaryOperator<T> firstWinsMerger() { - return (u,v) -> u; - } - - /** - * Returns a merge function, suitable for use in - * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or - * {@link #toMap(Function, Function, BinaryOperator) toMap()}, - * which implements a "last wins" policy. - * - * @param <T> the type of input arguments to the merge function - * @return a merge function which always returns its second argument - * @see #firstWinsMerger() - * @see #throwingMerger() - */ - public static <T> BinaryOperator<T> lastWinsMerger() { - return (u,v) -> v; - } - - /** * Simple implementation class for {@code Collector}. * * @param <T> the type of elements to be collected * @param <R> the type of the result */ - private static final class CollectorImpl<T, R> implements Collector<T,R> { - private final Supplier<R> resultSupplier; - private final BiFunction<R, T, R> accumulator; - private final BinaryOperator<R> combiner; + static class CollectorImpl<T, A, R> implements Collector<T, A, R> { + private final Supplier<A> supplier; + private final BiConsumer<A, T> accumulator; + private final BinaryOperator<A> combiner; + private final Function<A, R> finisher; private final Set<Characteristics> characteristics; - CollectorImpl(Supplier<R> resultSupplier, - BiFunction<R, T, R> accumulator, - BinaryOperator<R> combiner, + CollectorImpl(Supplier<A> supplier, + BiConsumer<A, T> accumulator, + BinaryOperator<A> combiner, + Function<A,R> finisher, Set<Characteristics> characteristics) { - this.resultSupplier = resultSupplier; + this.supplier = supplier; this.accumulator = accumulator; this.combiner = combiner; + this.finisher = finisher; this.characteristics = characteristics; } - CollectorImpl(Supplier<R> resultSupplier, - BiFunction<R, T, R> accumulator, - BinaryOperator<R> combiner) { - this(resultSupplier, accumulator, combiner, Collections.emptySet()); + CollectorImpl(Supplier<A> supplier, + BiConsumer<A, T> accumulator, + BinaryOperator<A> combiner, + Set<Characteristics> characteristics) { + this(supplier, accumulator, combiner, i -> (R) i, characteristics); } @Override - public BiFunction<R, T, R> accumulator() { + public BiConsumer<A, T> accumulator() { return accumulator; } @Override - public Supplier<R> resultSupplier() { - return resultSupplier; + public Supplier<A> supplier() { + return supplier; } @Override - public BinaryOperator<R> combiner() { + public BinaryOperator<A> combiner() { return combiner; } @Override + public Function<A, R> finisher() { + return finisher; + } + + @Override public Set<Characteristics> characteristics() { return characteristics; } @@ -224,11 +208,10 @@ * {@code Collection}, in encounter order */ public static <T, C extends Collection<T>> - Collector<T, C> toCollection(Supplier<C> collectionFactory) { - return new CollectorImpl<>(collectionFactory, - (r, t) -> { r.add(t); return r; }, + Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) { + return new CollectorImpl<>(collectionFactory, Collection::add, (r1, r2) -> { r1.addAll(r2); return r1; }, - CH_STRICT); + CH_ID); } /** @@ -241,36 +224,10 @@ * {@code List}, in encounter order */ public static <T> - Collector<T, List<T>> toList() { - BiFunction<List<T>, T, List<T>> accumulator = (list, t) -> { - switch (list.size()) { - case 0: - return Collections.singletonList(t); - case 1: - List<T> newList = new ArrayList<>(); - newList.add(list.get(0)); - newList.add(t); - return newList; - default: - list.add(t); - return list; - } - }; - BinaryOperator<List<T>> combiner = (left, right) -> { - switch (left.size()) { - case 0: - return right; - case 1: - List<T> newList = new ArrayList<>(left.size() + right.size()); - newList.addAll(left); - newList.addAll(right); - return newList; - default: - left.addAll(right); - return left; - } - }; - return new CollectorImpl<>(Collections::emptyList, accumulator, combiner); + Collector<T, ?, List<T>> toList() { + return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add, + (left, right) -> { left.addAll(right); return left; }, + CH_ID); } /** @@ -286,44 +243,58 @@ * {@code Set} */ public static <T> - Collector<T, Set<T>> toSet() { - return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, - (r, t) -> { r.add(t); return r; }, - (r1, r2) -> { r1.addAll(r2); return r1; }, - CH_STRICT_UNORDERED); + Collector<T, ?, Set<T>> toSet() { + return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add, + (left, right) -> { left.addAll(right); return left; }, + CH_UNORDERED_ID); } /** * Returns a {@code Collector} that concatenates the input elements into a - * new {@link StringBuilder}. + * {@code String}, in encounter order. * - * @return a {@code Collector} which collects String elements into a - * {@code StringBuilder}, in encounter order + * @return a {@code Collector} that concatenates the input elements into a + * {@code String}, in encounter order */ - public static Collector<String, StringBuilder> toStringBuilder() { - return new CollectorImpl<>(StringBuilder::new, - (r, t) -> { r.append(t); return r; }, - (r1, r2) -> { r1.append(r2); return r1; }, - CH_STRICT); + public static Collector<CharSequence, ?, String> joining() { + return new CollectorImpl<CharSequence, StringBuilder, String>( + StringBuilder::new, StringBuilder::append, + (r1, r2) -> { r1.append(r2); return r1; }, + StringBuilder::toString, CH_NOID); } /** - * Returns a {@code Collector} that concatenates the input elements into a - * new {@link StringJoiner}, using the specified delimiter. + * Returns a {@code Collector} that concatenates the input elements, + * separated by the specified delimiter, in encounter order. * * @param delimiter the delimiter to be used between each element - * @return A {@code Collector} which collects String elements into a - * {@code StringJoiner}, in encounter order + * @return A {@code Collector} which concatenates CharSequence elements, + * separated by the specified delimiter, in encounter order */ - public static Collector<CharSequence, StringJoiner> toStringJoiner(CharSequence delimiter) { - BinaryOperator<StringJoiner> merger = (sj, other) -> { - if (other.length() > 0) - sj.add(other.toString()); - return sj; - }; - return new CollectorImpl<>(() -> new StringJoiner(delimiter), - (r, t) -> { r.add(t); return r; }, - merger, CH_STRICT); + public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) { + return joining(delimiter, "", ""); + } + + /** + * Returns a {@code Collector} that concatenates the input elements, + * separated by the specified delimiter, with the specified prefix and + * suffix, in encounter order. + * + * @param delimiter the delimiter to be used between each element + * @param prefix the sequence of characters to be used at the beginning + * of the joined result + * @param suffix the sequence of characters to be used at the end + * of the joined result + * @return A {@code Collector} which concatenates CharSequence elements, + * separated by the specified delimiter, in encounter order + */ + public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, + CharSequence prefix, + CharSequence suffix) { + return new CollectorImpl<>( + () -> new StringJoiner(delimiter, prefix, suffix), + StringJoiner::add, StringJoiner::merge, + StringJoiner::toString, CH_NOID); } /** @@ -348,12 +319,13 @@ } /** - * Adapts a {@code Collector<U,R>} to a {@code Collector<T,R>} by applying - * a mapping function to each input element before accumulation. + * Adapts a {@code Collector} accepting elements of type {@code U} to one + * accepting elements of type {@code T} by applying a mapping function to + * each input element before accumulation. * * @apiNote * The {@code mapping()} collectors are most useful when used in a - * multi-level reduction, downstream of {@code groupingBy} or + * multi-level reduction, such as downstream of a {@code groupingBy} or * {@code partitioningBy}. For example, given a stream of * {@code Person}, to accumulate the set of last names in each city: * <pre>{@code @@ -364,23 +336,27 @@ * * @param <T> the type of the input elements * @param <U> type of elements accepted by downstream collector + * @param <A> intermediate accumulation type of the downstream collector * @param <R> result type of collector * @param mapper a function to be applied to the input elements * @param downstream a collector which will accept mapped values * @return a collector which applies the mapping function to the input * elements and provides the mapped results to the downstream collector */ - public static <T, U, R> Collector<T, R> - mapping(Function<? super T, ? extends U> mapper, Collector<? super U, R> downstream) { - BiFunction<R, ? super U, R> downstreamAccumulator = downstream.accumulator(); - return new CollectorImpl<>(downstream.resultSupplier(), - (r, t) -> downstreamAccumulator.apply(r, mapper.apply(t)), - downstream.combiner(), downstream.characteristics()); + public static <T, U, A, R> + Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, + Collector<? super U, A, R> downstream) { + BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator(); + return new CollectorImpl<>(downstream.supplier(), + (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)), + downstream.combiner(), downstream.finisher(), + downstream.characteristics()); } /** - * Returns a {@code Collector<T, Long>} that counts the number of input - * elements. + * Returns a {@code Collector} accepting elements of type {@code T} that + * counts the number of input elements. If no elements are present, the + * result is 0. * * @implSpec * This produces a result equivalent to: @@ -391,14 +367,14 @@ * @param <T> the type of the input elements * @return a {@code Collector} that counts the input elements */ - public static <T> Collector<T, Long> + public static <T> Collector<T, ?, Long> counting() { return reducing(0L, e -> 1L, Long::sum); } /** - * Returns a {@code Collector<T, T>} that produces the minimal element - * according to a given {@code Comparator}. + * Returns a {@code Collector} that produces the minimal element according + * to a given {@code Comparator}, described as an {@code Optional<T>}. * * @implSpec * This produces a result equivalent to: @@ -410,14 +386,14 @@ * @param comparator a {@code Comparator} for comparing elements * @return a {@code Collector} that produces the minimal value */ - public static <T> Collector<T, T> + public static <T> Collector<T, ?, Optional<T>> minBy(Comparator<? super T> comparator) { return reducing(BinaryOperator.minBy(comparator)); } /** - * Returns a {@code Collector<T, T>} that produces the maximal element - * according to a given {@code Comparator}. + * Returns a {@code Collector} that produces the maximal element according + * to a given {@code Comparator}, described as an {@code Optional<T>}. * * @implSpec * This produces a result equivalent to: @@ -429,39 +405,143 @@ * @param comparator a {@code Comparator} for comparing elements * @return a {@code Collector} that produces the maximal value */ - public static <T> Collector<T, T> + public static <T> Collector<T, ?, Optional<T>> maxBy(Comparator<? super T> comparator) { return reducing(BinaryOperator.maxBy(comparator)); } /** - * Returns a {@code Collector<T, Long>} that produces the sum of a - * long-valued function applied to the input element. + * Returns a {@code Collector} that produces the sum of a integer-valued + * function applied to the input elements. If no elements are present, + * the result is 0. + * + * @param <T> the type of the input elements + * @param mapper a function extracting the property to be summed + * @return a {@code Collector} that produces the sum of a derived property + */ + public static <T> Collector<T, ?, Integer> + summingInt(ToIntFunction<? super T> mapper) { + return new CollectorImpl<T, int[], Integer>( + () -> new int[1], + (a, t) -> { a[0] += mapper.applyAsInt(t); }, + (a, b) -> { a[0] += b[0]; return a; }, + a -> a[0], CH_NOID); + } + + /** + * Returns a {@code Collector} that produces the sum of a long-valued + * function applied to the input elements. If no elements are present, + * the result is 0. * - * @implSpec - * This produces a result equivalent to: - * <pre>{@code - * reducing(0L, mapper, Long::sum) - * }</pre> + * @param <T> the type of the input elements + * @param mapper a function extracting the property to be summed + * @return a {@code Collector} that produces the sum of a derived property + */ + public static <T> Collector<T, ?, Long> + summingLong(ToLongFunction<? super T> mapper) { + return new CollectorImpl<T, long[], Long>( + () -> new long[1], + (a, t) -> { a[0] += mapper.applyAsLong(t); }, + (a, b) -> { a[0] += b[0]; return a; }, + a -> a[0], CH_NOID); + } + + /** + * Returns a {@code Collector} that produces the sum of a double-valued + * function applied to the input elements. If no elements are present, + * the result is 0. + * + * <p>The sum returned can vary depending upon the order in which + * values are recorded, due to accumulated rounding error in + * addition of values of differing magnitudes. Values sorted by increasing + * absolute magnitude tend to yield more accurate results. If any recorded + * value is a {@code NaN} or the sum is at any point a {@code NaN} then the + * sum will be {@code NaN}. * * @param <T> the type of the input elements * @param mapper a function extracting the property to be summed * @return a {@code Collector} that produces the sum of a derived property */ - public static <T> Collector<T, Long> - sumBy(Function<? super T, Long> mapper) { - return reducing(0L, mapper, Long::sum); + public static <T> Collector<T, ?, Double> + summingDouble(ToDoubleFunction<? super T> mapper) { + return new CollectorImpl<T, double[], Double>( + () -> new double[1], + (a, t) -> { a[0] += mapper.applyAsDouble(t); }, + (a, b) -> { a[0] += b[0]; return a; }, + a -> a[0], CH_NOID); + } + + /** + * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued + * function applied to the input elements. If no elements are present, + * the result is 0. + * + * @param <T> the type of the input elements + * @param mapper a function extracting the property to be summed + * @return a {@code Collector} that produces the sum of a derived property + */ + public static <T> Collector<T, ?, Double> + averagingInt(ToIntFunction<? super T> mapper) { + return new CollectorImpl<T, long[], Double>( + () -> new long[2], + (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; }, + (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, + a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID); } /** - * Returns a {@code Collector<T,T>} which performs a reduction of its - * input elements under a specified {@code BinaryOperator}. + * Returns a {@code Collector} that produces the arithmetic mean of a long-valued + * function applied to the input elements. If no elements are present, + * the result is 0. + * + * @param <T> the type of the input elements + * @param mapper a function extracting the property to be summed + * @return a {@code Collector} that produces the sum of a derived property + */ + public static <T> Collector<T, ?, Double> + averagingLong(ToLongFunction<? super T> mapper) { + return new CollectorImpl<T, long[], Double>( + () -> new long[2], + (a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; }, + (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, + a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID); + } + + /** + * Returns a {@code Collector} that produces the arithmetic mean of a double-valued + * function applied to the input elements. If no elements are present, + * the result is 0. + * + * <p>The average returned can vary depending upon the order in which + * values are recorded, due to accumulated rounding error in + * addition of values of differing magnitudes. Values sorted by increasing + * absolute magnitude tend to yield more accurate results. If any recorded + * value is a {@code NaN} or the sum is at any point a {@code NaN} then the + * average will be {@code NaN}. + * + * @param <T> the type of the input elements + * @param mapper a function extracting the property to be summed + * @return a {@code Collector} that produces the sum of a derived property + */ + public static <T> Collector<T, ?, Double> + averagingDouble(ToDoubleFunction<? super T> mapper) { + return new CollectorImpl<T, double[], Double>( + () -> new double[2], + (a, t) -> { a[0] += mapper.applyAsDouble(t); a[1]++; }, + (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, + a -> (a[1] == 0) ? 0.0d : a[0] / a[1], CH_NOID); + } + + /** + * Returns a {@code Collector} which performs a reduction of its + * input elements under a specified {@code BinaryOperator} using the + * provided identity. * * @apiNote * The {@code reducing()} collectors are most useful when used in a * multi-level reduction, downstream of {@code groupingBy} or * {@code partitioningBy}. To perform a simple reduction on a stream, - * use {@link Stream#reduce(BinaryOperator)} instead. + * use {@link Stream#reduce(Object, BinaryOperator)}} instead. * * @param <T> element type for the input and output of the reduction * @param identity the identity value for the reduction (also, the value @@ -472,14 +552,25 @@ * @see #reducing(BinaryOperator) * @see #reducing(Object, Function, BinaryOperator) */ - public static <T> Collector<T, T> + public static <T> Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op) { - return new CollectorImpl<>(() -> identity, (r, t) -> (r == null ? t : op.apply(r, t)), op); + return new CollectorImpl<>( + boxSupplier(identity), + (a, t) -> { a[0] = op.apply(a[0], t); }, + (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; }, + a -> a[0], + CH_NOID); + } + + @SuppressWarnings("unchecked") + private static <T> Supplier<T[]> boxSupplier(T identity) { + return () -> (T[]) new Object[] { identity }; } /** - * Returns a {@code Collector<T,T>} which performs a reduction of its - * input elements under a specified {@code BinaryOperator}. + * Returns a {@code Collector} which performs a reduction of its + * input elements under a specified {@code BinaryOperator}. The result + * is described as an {@code Optional<T>}. * * @apiNote * The {@code reducing()} collectors are most useful when used in a @@ -491,15 +582,8 @@ * person in each city: * <pre>{@code * Comparator<Person> byHeight = Comparator.comparing(Person::getHeight); - * BinaryOperator<Person> tallerOf = BinaryOperator.greaterOf(byHeight); * Map<City, Person> tallestByCity - * = people.stream().collect(groupingBy(Person::getCity, reducing(tallerOf))); - * }</pre> - * - * @implSpec - * The default implementation is equivalent to: - * <pre>{@code - * reducing(null, op); + * = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight)))); * }</pre> * * @param <T> element type for the input and output of the reduction @@ -509,13 +593,32 @@ * @see #reducing(Object, BinaryOperator) * @see #reducing(Object, Function, BinaryOperator) */ - public static <T> Collector<T, T> + public static <T> Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op) { - return reducing(null, op); + class OptionalBox implements Consumer<T> { + T value = null; + boolean present = false; + + @Override + public void accept(T t) { + if (present) { + value = op.apply(value, t); + } + else { + value = t; + present = true; + } + } + } + + return new CollectorImpl<T, OptionalBox, Optional<T>>( + OptionalBox::new, OptionalBox::accept, + (a, b) -> { if (b.present) a.accept(b.value); return a; }, + a -> Optional.ofNullable(a.value), CH_NOID); } /** - * Returns a {@code Collector<T,U>} which performs a reduction of its + * Returns a {@code Collector} which performs a reduction of its * input elements under a specified mapping function and * {@code BinaryOperator}. This is a generalization of * {@link #reducing(Object, BinaryOperator)} which allows a transformation @@ -524,17 +627,17 @@ * @apiNote * The {@code reducing()} collectors are most useful when used in a * multi-level reduction, downstream of {@code groupingBy} or - * {@code partitioningBy}. To perform a simple reduction on a stream, - * use {@link Stream#reduce(BinaryOperator)} instead. + * {@code partitioningBy}. To perform a simple map-reduce on a stream, + * use {@link Stream#map(Function)} and {@link Stream#reduce(Object, BinaryOperator)} + * instead. * * <p>For example, given a stream of {@code Person}, to calculate the longest * last name of residents in each city: * <pre>{@code * Comparator<String> byLength = Comparator.comparing(String::length); - * BinaryOperator<String> longerOf = BinaryOperator.greaterOf(byLength); * Map<City, String> longestLastNameByCity * = people.stream().collect(groupingBy(Person::getCity, - * reducing(Person::getLastName, longerOf))); + * reducing(Person::getLastName, BinaryOperator.maxBy(byLength)))); * }</pre> * * @param <T> the type of the input elements @@ -549,18 +652,20 @@ * @see #reducing(BinaryOperator) */ public static <T, U> - Collector<T, U> reducing(U identity, - Function<? super T, ? extends U> mapper, - BinaryOperator<U> op) { - return new CollectorImpl<>(() -> identity, - (r, t) -> (r == null ? mapper.apply(t) : op.apply(r, mapper.apply(t))), - op); + Collector<T, ?, U> reducing(U identity, + Function<? super T, ? extends U> mapper, + BinaryOperator<U> op) { + return new CollectorImpl<>( + boxSupplier(identity), + (a, t) -> { a[0] = op.apply(a[0], mapper.apply(t)); }, + (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; }, + a -> a[0], CH_NOID); } /** * Returns a {@code Collector} implementing a "group by" operation on * input elements of type {@code T}, grouping elements according to a - * classification function. + * classification function, and returning the results in a {@code Map}. * * <p>The classification function maps elements to some key type {@code K}. * The collector produces a {@code Map<K, List<T>>} whose keys are the @@ -586,9 +691,9 @@ * @see #groupingBy(Function, Supplier, Collector) * @see #groupingByConcurrent(Function) */ - public static <T, K> - Collector<T, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) { - return groupingBy(classifier, HashMap::new, toList()); + public static <T, K> Collector<T, ?, Map<K, List<T>>> + groupingBy(Function<? super T, ? extends K> classifier) { + return groupingBy(classifier, toList()); } /** @@ -615,6 +720,7 @@ * * @param <T> the type of the input elements * @param <K> the type of the keys + * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param classifier a classifier function mapping input elements to keys * @param downstream a {@code Collector} implementing the downstream reduction @@ -624,9 +730,9 @@ * @see #groupingBy(Function, Supplier, Collector) * @see #groupingByConcurrent(Function, Collector) */ - public static <T, K, D> - Collector<T, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, - Collector<? super T, D> downstream) { + public static <T, K, A, D> + Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, + Collector<? super T, A, D> downstream) { return groupingBy(classifier, HashMap::new, downstream); } @@ -653,6 +759,7 @@ * * @param <T> the type of the input elements * @param <K> the type of the keys + * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param <M> the type of the resulting {@code Map} * @param classifier a classifier function mapping input elements to keys @@ -665,25 +772,39 @@ * @see #groupingBy(Function) * @see #groupingByConcurrent(Function, Supplier, Collector) */ - public static <T, K, D, M extends Map<K, D>> - Collector<T, M> groupingBy(Function<? super T, ? extends K> classifier, - Supplier<M> mapFactory, - Collector<? super T, D> downstream) { - Supplier<D> downstreamSupplier = downstream.resultSupplier(); - BiFunction<D, ? super T, D> downstreamAccumulator = downstream.accumulator(); - BiFunction<M, T, M> accumulator = (m, t) -> { + public static <T, K, D, A, M extends Map<K, D>> + Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, + Supplier<M> mapFactory, + Collector<? super T, A, D> downstream) { + Supplier<A> downstreamSupplier = downstream.supplier(); + BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator(); + BiConsumer<Map<K, A>, T> accumulator = (m, t) -> { K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key"); - D oldContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get()); - D newContainer = downstreamAccumulator.apply(oldContainer, t); - if (newContainer != oldContainer) - m.put(key, newContainer); - return m; + A container = m.computeIfAbsent(key, k -> downstreamSupplier.get()); + downstreamAccumulator.accept(container, t); }; - return new CollectorImpl<>(mapFactory, accumulator, mapMerger(downstream.combiner()), CH_STRICT); + BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner()); + @SuppressWarnings("unchecked") + Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory; + + if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { + return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID); + } + else { + @SuppressWarnings("unchecked") + Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher(); + Function<Map<K, A>, M> finisher = intermediate -> { + intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v)); + @SuppressWarnings("unchecked") + M castResult = (M) intermediate; + return castResult; + }; + return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID); + } } /** - * Returns a {@code Collector} implementing a concurrent "group by" + * Returns a concurrent {@code Collector} implementing a "group by" * operation on input elements of type {@code T}, grouping elements * according to a classification function. * @@ -716,12 +837,13 @@ * @see #groupingByConcurrent(Function, Supplier, Collector) */ public static <T, K> - Collector<T, ConcurrentMap<K, List<T>>> groupingByConcurrent(Function<? super T, ? extends K> classifier) { + Collector<T, ?, ConcurrentMap<K, List<T>>> + groupingByConcurrent(Function<? super T, ? extends K> classifier) { return groupingByConcurrent(classifier, ConcurrentHashMap::new, toList()); } /** - * Returns a {@code Collector} implementing a concurrent cascaded "group by" + * Returns a concurrent {@code Collector} implementing a cascaded "group by" * operation on input elements of type {@code T}, grouping elements * according to a classification function, and then performing a reduction * operation on the values associated with a given key using the specified @@ -739,12 +861,13 @@ * where the city names are sorted: * <pre>{@code * ConcurrentMap<City, Set<String>> namesByCity - * = people.stream().collect(groupingByConcurrent(Person::getCity, TreeMap::new, + * = people.stream().collect(groupingByConcurrent(Person::getCity, ConcurrentSkipListMap::new, * mapping(Person::getLastName, toSet()))); * }</pre> * * @param <T> the type of the input elements * @param <K> the type of the keys + * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param classifier a classifier function mapping input elements to keys * @param downstream a {@code Collector} implementing the downstream reduction @@ -754,9 +877,9 @@ * @see #groupingByConcurrent(Function) * @see #groupingByConcurrent(Function, Supplier, Collector) */ - public static <T, K, D> - Collector<T, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier, - Collector<? super T, D> downstream) { + public static <T, K, A, D> + Collector<T, ?, ConcurrentMap<K, D>> groupingByConcurrent(Function<? super T, ? extends K> classifier, + Collector<? super T, A, D> downstream) { return groupingByConcurrent(classifier, ConcurrentHashMap::new, downstream); } @@ -787,6 +910,7 @@ * * @param <T> the type of the input elements * @param <K> the type of the keys + * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param <M> the type of the resulting {@code ConcurrentMap} * @param classifier a classifier function mapping input elements to keys @@ -799,51 +923,46 @@ * @see #groupingByConcurrent(Function, Collector) * @see #groupingBy(Function, Supplier, Collector) */ - public static <T, K, D, M extends ConcurrentMap<K, D>> - Collector<T, M> groupingByConcurrent(Function<? super T, ? extends K> classifier, - Supplier<M> mapFactory, - Collector<? super T, D> downstream) { - Supplier<D> downstreamSupplier = downstream.resultSupplier(); - BiFunction<D, ? super T, D> downstreamAccumulator = downstream.accumulator(); - BinaryOperator<M> combiner = mapMerger(downstream.combiner()); + public static <T, K, A, D, M extends ConcurrentMap<K, D>> + Collector<T, ?, M> groupingByConcurrent(Function<? super T, ? extends K> classifier, + Supplier<M> mapFactory, + Collector<? super T, A, D> downstream) { + Supplier<A> downstreamSupplier = downstream.supplier(); + BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator(); + BinaryOperator<ConcurrentMap<K, A>> merger = Collectors.<K, A, ConcurrentMap<K, A>>mapMerger(downstream.combiner()); + @SuppressWarnings("unchecked") + Supplier<ConcurrentMap<K, A>> mangledFactory = (Supplier<ConcurrentMap<K, A>>) mapFactory; + BiConsumer<ConcurrentMap<K, A>, T> accumulator; if (downstream.characteristics().contains(Collector.Characteristics.CONCURRENT)) { - BiFunction<M, T, M> accumulator = (m, t) -> { + accumulator = (m, t) -> { K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key"); - downstreamAccumulator.apply(m.computeIfAbsent(key, k -> downstreamSupplier.get()), t); - return m; - }; - return new CollectorImpl<>(mapFactory, accumulator, combiner, CH_CONCURRENT); - } else if (downstream.characteristics().contains(Collector.Characteristics.STRICTLY_MUTATIVE)) { - BiFunction<M, T, M> accumulator = (m, t) -> { - K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key"); - D resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get()); - synchronized (resultContainer) { - downstreamAccumulator.apply(resultContainer, t); - } - return m; + A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get()); + downstreamAccumulator.accept(resultContainer, t); }; - return new CollectorImpl<>(mapFactory, accumulator, combiner, CH_CONCURRENT); - } else { - BiFunction<M, T, M> accumulator = (m, t) -> { + } + else { + accumulator = (m, t) -> { K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key"); - do { - D oldResult = m.computeIfAbsent(key, k -> downstreamSupplier.get()); - if (oldResult == null) { - if (m.putIfAbsent(key, downstreamAccumulator.apply(null, t)) == null) - return m; - } else { - synchronized (oldResult) { - if (m.get(key) != oldResult) - continue; - D newResult = downstreamAccumulator.apply(oldResult, t); - if (oldResult != newResult) - m.put(key, newResult); - return m; - } - } - } while (true); + A resultContainer = m.computeIfAbsent(key, k -> downstreamSupplier.get()); + synchronized (resultContainer) { + downstreamAccumulator.accept(resultContainer, t); + } }; - return new CollectorImpl<>(mapFactory, accumulator, combiner, CH_CONCURRENT); + } + + if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { + return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_CONCURRENT_ID); + } + else { + @SuppressWarnings("unchecked") + Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher(); + Function<ConcurrentMap<K, A>, M> finisher = intermediate -> { + intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v)); + @SuppressWarnings("unchecked") + M castResult = (M) intermediate; + return castResult; + }; + return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_CONCURRENT_NOID); } } @@ -862,7 +981,7 @@ * @see #partitioningBy(Predicate, Collector) */ public static <T> - Collector<T, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) { + Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) { return partitioningBy(predicate, toList()); } @@ -877,6 +996,7 @@ * serializability, or thread-safety of the {@code Map} returned. * * @param <T> the type of the input elements + * @param <A> the intermediate accumulation type of the downstream collector * @param <D> the result type of the downstream reduction * @param predicate a predicate used for classifying input elements * @param downstream a {@code Collector} implementing the downstream @@ -886,52 +1006,43 @@ * * @see #partitioningBy(Predicate) */ - public static <T, D> - Collector<T, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate, - Collector<? super T, D> downstream) { - BiFunction<D, ? super T, D> downstreamAccumulator = downstream.accumulator(); - BiFunction<Map<Boolean, D>, T, Map<Boolean, D>> accumulator = (result, t) -> { + public static <T, D, A> + Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate, + Collector<? super T, A, D> downstream) { + @SuppressWarnings("unchecked") + BiConsumer<D, ? super T> downstreamAccumulator = (BiConsumer<D, ? super T>) downstream.accumulator(); + BiConsumer<Map<Boolean, A>, T> accumulator = (result, t) -> { Partition<D> asPartition = ((Partition<D>) result); - if (predicate.test(t)) { - D newResult = downstreamAccumulator.apply(asPartition.forTrue, t); - if (newResult != asPartition.forTrue) - asPartition.forTrue = newResult; - } else { - D newResult = downstreamAccumulator.apply(asPartition.forFalse, t); - if (newResult != asPartition.forFalse) - asPartition.forFalse = newResult; - } - return result; + downstreamAccumulator.accept(predicate.test(t) ? asPartition.forTrue : asPartition.forFalse, t); + }; + BinaryOperator<A> op = downstream.combiner(); + BinaryOperator<Map<Boolean, A>> merger = (m1, m2) -> { + Partition<A> left = (Partition<A>) m1; + Partition<A> right = (Partition<A>) m2; + return new Partition<>(op.apply(left.forTrue, right.forTrue), + op.apply(left.forFalse, right.forFalse)); }; - return new CollectorImpl<>(() -> new Partition<>(downstream.resultSupplier().get(), - downstream.resultSupplier().get()), - accumulator, partitionMerger(downstream.combiner()), CH_STRICT); + Supplier<Map<Boolean, A>> supplier = () -> new Partition<>(downstream.supplier().get(), + downstream.supplier().get()); + if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { + return new CollectorImpl<>(supplier, accumulator, merger, CH_ID); + } + else { + Function<Map<Boolean, A>, Map<Boolean, D>> finisher = (Map<Boolean, A> par) -> { + Partition<A> asAPartition = (Partition<A>) par; + return new Partition<>(downstream.finisher().apply(asAPartition.forTrue), + downstream.finisher().apply(asAPartition.forFalse)); + }; + return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID); + } } /** - * Merge function for two partitions, given a merge function for the - * elements. - */ - private static <D> BinaryOperator<Map<Boolean, D>> partitionMerger(BinaryOperator<D> op) { - return (m1, m2) -> { - Partition<D> left = (Partition<D>) m1; - Partition<D> right = (Partition<D>) m2; - if (left.forFalse == null) - left.forFalse = right.forFalse; - else if (right.forFalse != null) - left.forFalse = op.apply(left.forFalse, right.forFalse); - if (left.forTrue == null) - left.forTrue = right.forTrue; - else if (right.forTrue != null) - left.forTrue = op.apply(left.forTrue, right.forTrue); - return left; - }; - } - - /** - * Accumulate elements into a {@code Map} whose keys and values are the - * result of applying mapping functions to the input elements. - * If the mapped keys contains duplicates (according to + * Returns a {@code Collector} that accumulate elements into a + * {@code Map} whose keys and values are the result of applying the provided + * mapping functions to the input elements. + * + * <p>If the mapped keys contains duplicates (according to * {@link Object#equals(Object)}), an {@code IllegalStateException} is * thrown when the collection operation is performed. If the mapped keys * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)} @@ -970,24 +1081,26 @@ * @see #toConcurrentMap(Function, Function) */ public static <T, K, U> - Collector<T, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, - Function<? super T, ? extends U> valueMapper) { + Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, + Function<? super T, ? extends U> valueMapper) { return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); } /** - * Accumulate elements into a {@code Map} whose keys and values are the - * result of applying mapping functions to the input elements. If the mapped + * Returns a {@code Collector} that accumulate elements into a + * {@code Map} whose keys and values are the result of applying the provided + * mapping functions to the input elements. + * + * <p>If the mapped * keys contains duplicates (according to {@link Object#equals(Object)}), * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. * * @apiNote * There are multiple ways to deal with collisions between multiple elements - * mapping to the same key. There are some predefined merging functions, - * such as {@link #throwingMerger()}, {@link #firstWinsMerger()}, and - * {@link #lastWinsMerger()}, that implement common policies, or you can - * implement custom policies easily. For example, if you have a stream + * mapping to the same key. The other forms of {@code toMap} simply use + * a merge function that throws unconditionally, but you can easily write + * more flexible merge policies. For example, if you have a stream * of {@code Person}, and you want to produce a "phone book" mapping name to * address, but it is possible that two persons have the same name, you can * do as follows to gracefully deals with these collisions, and produce a @@ -1018,15 +1131,18 @@ * @see #toConcurrentMap(Function, Function, BinaryOperator) */ public static <T, K, U> - Collector<T, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, - Function<? super T, ? extends U> valueMapper, - BinaryOperator<U> mergeFunction) { + Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, + Function<? super T, ? extends U> valueMapper, + BinaryOperator<U> mergeFunction) { return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); } /** - * Accumulate elements into a {@code Map} whose keys and values are the - * result of applying mapping functions to the input elements. If the mapped + * Returns a {@code Collector} that accumulate elements into a + * {@code Map} whose keys and values are the result of applying the provided + * mapping functions to the input elements. + * + * <p>If the mapped * keys contains duplicates (according to {@link Object#equals(Object)}), * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. The {@code Map} @@ -1054,22 +1170,22 @@ * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier) */ public static <T, K, U, M extends Map<K, U>> - Collector<T, M> toMap(Function<? super T, ? extends K> keyMapper, - Function<? super T, ? extends U> valueMapper, - BinaryOperator<U> mergeFunction, - Supplier<M> mapSupplier) { - BiFunction<M, T, M> accumulator - = (map, element) -> { - map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction); - return map; - }; - return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_STRICT); + Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper, + Function<? super T, ? extends U> valueMapper, + BinaryOperator<U> mergeFunction, + Supplier<M> mapSupplier) { + BiConsumer<M, T> accumulator + = (map, element) -> map.merge(keyMapper.apply(element), + valueMapper.apply(element), mergeFunction); + return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID); } /** - * Accumulate elements into a {@code ConcurrentMap} whose keys and values - * are the result of applying mapping functions to the input elements. - * If the mapped keys contains duplicates (according to + * Returns a {@code Collector} that accumulate elements into a + * {@code ConcurrentMap} whose keys and values are the result of applying + * the provided mapping functions to the input elements. + * + * <p>If the mapped keys contains duplicates (according to * {@link Object#equals(Object)}), an {@code IllegalStateException} is * thrown when the collection operation is performed. If the mapped keys * may have duplicates, use @@ -1112,24 +1228,25 @@ * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier) */ public static <T, K, U> - Collector<T, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper, - Function<? super T, ? extends U> valueMapper) { + Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper, + Function<? super T, ? extends U> valueMapper) { return toConcurrentMap(keyMapper, valueMapper, throwingMerger(), ConcurrentHashMap::new); } /** - * Accumulate elements into a {@code ConcurrentMap} whose keys and values - * are the result of applying mapping functions to the input elements. If - * the mapped keys contains duplicates (according to {@link Object#equals(Object)}), + * Returns a {@code Collector} that accumulate elements into a + * {@code ConcurrentMap} whose keys and values are the result of applying + * the provided mapping functions to the input elements. + * + * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}), * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. * * @apiNote * There are multiple ways to deal with collisions between multiple elements - * mapping to the same key. There are some predefined merging functions, - * such as {@link #throwingMerger()}, {@link #firstWinsMerger()}, and - * {@link #lastWinsMerger()}, that implement common policies, or you can - * implement custom policies easily. For example, if you have a stream + * mapping to the same key. The other forms of {@code toConcurrentMap} simply use + * a merge function that throws unconditionally, but you can easily write + * more flexible merge policies. For example, if you have a stream * of {@code Person}, and you want to produce a "phone book" mapping name to * address, but it is possible that two persons have the same name, you can * do as follows to gracefully deals with these collisions, and produce a @@ -1163,16 +1280,19 @@ * @see #toMap(Function, Function, BinaryOperator) */ public static <T, K, U> - Collector<T, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper, - Function<? super T, ? extends U> valueMapper, - BinaryOperator<U> mergeFunction) { + Collector<T, ?, ConcurrentMap<K,U>> + toConcurrentMap(Function<? super T, ? extends K> keyMapper, + Function<? super T, ? extends U> valueMapper, + BinaryOperator<U> mergeFunction) { return toConcurrentMap(keyMapper, valueMapper, mergeFunction, ConcurrentHashMap::new); } /** - * Accumulate elements into a {@code ConcurrentMap} whose keys and values - * are the result of applying mapping functions to the input elements. If - * the mapped keys contains duplicates (according to {@link Object#equals(Object)}), + * Returns a {@code Collector} that accumulate elements into a + * {@code ConcurrentMap} whose keys and values are the result of applying + * the provided mapping functions to the input elements. + * + * <p>If the mapped keys contains duplicates (according to {@link Object#equals(Object)}), * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. The * {@code ConcurrentMap} is created by a provided supplier function. @@ -1202,15 +1322,14 @@ * @see #toMap(Function, Function, BinaryOperator, Supplier) */ public static <T, K, U, M extends ConcurrentMap<K, U>> - Collector<T, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper, - Function<? super T, ? extends U> valueMapper, - BinaryOperator<U> mergeFunction, - Supplier<M> mapSupplier) { - BiFunction<M, T, M> accumulator = (map, element) -> { - map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction); - return map; - }; - return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_CONCURRENT); + Collector<T, ?, M> toConcurrentMap(Function<? super T, ? extends K> keyMapper, + Function<? super T, ? extends U> valueMapper, + BinaryOperator<U> mergeFunction, + Supplier<M> mapSupplier) { + BiConsumer<M, T> accumulator + = (map, element) -> map.merge(keyMapper.apply(element), + valueMapper.apply(element), mergeFunction); + return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_CONCURRENT_ID); } /** @@ -1222,14 +1341,15 @@ * @param mapper a mapping function to apply to each element * @return a {@code Collector} implementing the summary-statistics reduction * - * @see #toDoubleSummaryStatistics(ToDoubleFunction) - * @see #toLongSummaryStatistics(ToLongFunction) + * @see #summarizingDouble(ToDoubleFunction) + * @see #summarizingLong(ToLongFunction) */ public static <T> - Collector<T, IntSummaryStatistics> toIntSummaryStatistics(ToIntFunction<? super T> mapper) { - return new CollectorImpl<>(IntSummaryStatistics::new, - (r, t) -> { r.accept(mapper.applyAsInt(t)); return r; }, - (l, r) -> { l.combine(r); return l; }, CH_STRICT); + Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) { + return new CollectorImpl<T, IntSummaryStatistics, IntSummaryStatistics>( + IntSummaryStatistics::new, + (r, t) -> r.accept(mapper.applyAsInt(t)), + (l, r) -> { l.combine(r); return l; }, CH_ID); } /** @@ -1241,14 +1361,15 @@ * @param mapper the mapping function to apply to each element * @return a {@code Collector} implementing the summary-statistics reduction * - * @see #toDoubleSummaryStatistics(ToDoubleFunction) - * @see #toIntSummaryStatistics(ToIntFunction) + * @see #summarizingDouble(ToDoubleFunction) + * @see #summarizingInt(ToIntFunction) */ public static <T> - Collector<T, LongSummaryStatistics> toLongSummaryStatistics(ToLongFunction<? super T> mapper) { - return new CollectorImpl<>(LongSummaryStatistics::new, - (r, t) -> { r.accept(mapper.applyAsLong(t)); return r; }, - (l, r) -> { l.combine(r); return l; }, CH_STRICT); + Collector<T, ?, LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) { + return new CollectorImpl<T, LongSummaryStatistics, LongSummaryStatistics>( + LongSummaryStatistics::new, + (r, t) -> r.accept(mapper.applyAsLong(t)), + (l, r) -> { l.combine(r); return l; }, CH_ID); } /** @@ -1260,14 +1381,15 @@ * @param mapper a mapping function to apply to each element * @return a {@code Collector} implementing the summary-statistics reduction * - * @see #toLongSummaryStatistics(ToLongFunction) - * @see #toIntSummaryStatistics(ToIntFunction) + * @see #summarizingLong(ToLongFunction) + * @see #summarizingInt(ToIntFunction) */ public static <T> - Collector<T, DoubleSummaryStatistics> toDoubleSummaryStatistics(ToDoubleFunction<? super T> mapper) { - return new CollectorImpl<>(DoubleSummaryStatistics::new, - (r, t) -> { r.accept(mapper.applyAsDouble(t)); return r; }, - (l, r) -> { l.combine(r); return l; }, CH_STRICT); + Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) { + return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>( + DoubleSummaryStatistics::new, + (r, t) -> r.accept(mapper.applyAsDouble(t)), + (l, r) -> { l.combine(r); return l; }, CH_ID); } /** @@ -1276,8 +1398,8 @@ private static final class Partition<T> extends AbstractMap<Boolean, T> implements Map<Boolean, T> { - T forTrue; - T forFalse; + final T forTrue; + final T forFalse; Partition(T forTrue, T forFalse) { this.forTrue = forTrue; @@ -1289,24 +1411,9 @@ return new AbstractSet<Map.Entry<Boolean, T>>() { @Override public Iterator<Map.Entry<Boolean, T>> iterator() { - - return new Iterator<Map.Entry<Boolean, T>>() { - int state = 0; - - @Override - public boolean hasNext() { - return state < 2; - } - - @Override - public Map.Entry<Boolean, T> next() { - if (state >= 2) - throw new NoSuchElementException(); - return (state++ == 0) - ? new SimpleImmutableEntry<>(false, forFalse) - : new SimpleImmutableEntry<>(true, forTrue); - } - }; + Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse); + Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue); + return Arrays.asList(falseEntry, trueEntry).iterator(); } @Override
--- a/src/share/classes/java/util/stream/DelegatingStream.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/DelegatingStream.java Wed Aug 07 19:56:20 2013 -0700 @@ -209,7 +209,7 @@ } @Override - public <R> R collect(Collector<? super T, R> collector) { + public <R, A> R collect(Collector<? super T, A, ? extends R> collector) { return delegate.collect(collector); }
--- a/src/share/classes/java/util/stream/DoublePipeline.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/DoublePipeline.java Wed Aug 07 19:56:20 2013 -0700 @@ -147,6 +147,7 @@ } @Override + @SuppressWarnings("unchecked") final Spliterator.OfDouble lazySpliterator(Supplier<? extends Spliterator<Double>> supplier) { return new StreamSpliterators.DelegatingSpliterator.OfDouble((Supplier<Spliterator.OfDouble>) supplier); } @@ -209,6 +210,7 @@ Sink<Double> opWrapSink(int flags, Sink<U> sink) { return new Sink.ChainedDouble(sink) { @Override + @SuppressWarnings("unchecked") public void accept(double t) { downstream.accept(mapper.apply(t)); }
--- a/src/share/classes/java/util/stream/DoubleStream.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/DoubleStream.java Wed Aug 07 19:56:20 2013 -0700 @@ -527,7 +527,7 @@ long count(); /** - * Returns an {@code OptionalDouble} describing the average of elements of + * Returns an {@code OptionalDouble} describing the arithmetic mean of elements of * this stream, or an empty optional if this stream is empty. The average * returned can vary depending upon the order in which elements are * encountered. This is due to accumulated rounding error in addition of
--- a/src/share/classes/java/util/stream/FindOps.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/FindOps.java Wed Aug 07 19:56:20 2013 -0700 @@ -246,6 +246,7 @@ * @param <P_OUT> Output element type from the stream pipeline * @param <O> Result type from the find operation */ + @SuppressWarnings("serial") private static final class FindTask<P_IN, P_OUT, O> extends AbstractShortCircuitTask<P_IN, P_OUT, O, FindTask<P_IN, P_OUT, O>> { private final FindOp<P_OUT, O> op;
--- a/src/share/classes/java/util/stream/ForEachOps.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/ForEachOps.java Wed Aug 07 19:56:20 2013 -0700 @@ -249,6 +249,7 @@ } /** A {@code ForkJoinTask} for performing a parallel for-each operation */ + @SuppressWarnings("serial") static final class ForEachTask<S, T> extends CountedCompleter<Void> { private Spliterator<S> spliterator; private final Sink<S> sink; @@ -314,6 +315,7 @@ * A {@code ForkJoinTask} for performing a parallel for-each operation * which visits the elements in encounter order */ + @SuppressWarnings("serial") static final class ForEachOrderedTask<S, T> extends CountedCompleter<Void> { private final PipelineHelper<T> helper; private Spliterator<S> spliterator;
--- a/src/share/classes/java/util/stream/IntPipeline.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/IntPipeline.java Wed Aug 07 19:56:20 2013 -0700 @@ -150,6 +150,7 @@ } @Override + @SuppressWarnings("unchecked") final Spliterator.OfInt lazySpliterator(Supplier<? extends Spliterator<Integer>> supplier) { return new StreamSpliterators.DelegatingSpliterator.OfInt((Supplier<Spliterator.OfInt>) supplier); } @@ -190,6 +191,7 @@ Sink<Integer> opWrapSink(int flags, Sink<Long> sink) { return new Sink.ChainedInt(sink) { @Override + @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept((long) t); } @@ -206,6 +208,7 @@ Sink<Integer> opWrapSink(int flags, Sink<Double> sink) { return new Sink.ChainedInt(sink) { @Override + @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept((double) t); } @@ -245,6 +248,7 @@ Sink<Integer> opWrapSink(int flags, Sink<U> sink) { return new Sink.ChainedInt(sink) { @Override + @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept(mapper.apply(t)); }
--- a/src/share/classes/java/util/stream/IntStream.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/IntStream.java Wed Aug 07 19:56:20 2013 -0700 @@ -517,7 +517,7 @@ long count(); /** - * Returns an {@code OptionalDouble} describing the average of elements of + * Returns an {@code OptionalDouble} describing the arithmetic mean of elements of * this stream, or an empty optional if this stream is empty. This is a * special case of a * <a href="package-summary.html#MutableReduction">reduction</a>.
--- a/src/share/classes/java/util/stream/LongPipeline.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/LongPipeline.java Wed Aug 07 19:56:20 2013 -0700 @@ -148,6 +148,7 @@ } @Override + @SuppressWarnings("unchecked") final Spliterator.OfLong lazySpliterator(Supplier<? extends Spliterator<Long>> supplier) { return new StreamSpliterators.DelegatingSpliterator.OfLong((Supplier<Spliterator.OfLong>) supplier); } @@ -209,6 +210,7 @@ Sink<Long> opWrapSink(int flags, Sink<Long> sink) { return new Sink.ChainedLong(sink) { @Override + @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.applyAsLong(t)); } @@ -226,6 +228,7 @@ Sink<Long> opWrapSink(int flags, Sink<U> sink) { return new Sink.ChainedLong(sink) { @Override + @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.apply(t)); } @@ -243,6 +246,7 @@ Sink<Long> opWrapSink(int flags, Sink<Integer> sink) { return new Sink.ChainedLong(sink) { @Override + @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.applyAsInt(t)); }
--- a/src/share/classes/java/util/stream/LongStream.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/LongStream.java Wed Aug 07 19:56:20 2013 -0700 @@ -517,7 +517,7 @@ long count(); /** - * Returns an {@code OptionalDouble} describing the average of elements of + * Returns an {@code OptionalDouble} describing the arithmetic mean of elements of * this stream, or an empty optional if this stream is empty. This is a * special case of a * <a href="package-summary.html#MutableReduction">reduction</a>.
--- a/src/share/classes/java/util/stream/MatchOps.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/MatchOps.java Wed Aug 07 19:56:20 2013 -0700 @@ -274,6 +274,7 @@ * @param <P_IN> the type of source elements for the pipeline * @param <P_OUT> the type of output elements for the pipeline */ + @SuppressWarnings("serial") private static final class MatchTask<P_IN, P_OUT> extends AbstractShortCircuitTask<P_IN, P_OUT, Boolean, MatchTask<P_IN, P_OUT>> { private final MatchOp<P_OUT> op;
--- a/src/share/classes/java/util/stream/Nodes.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/Nodes.java Wed Aug 07 19:56:20 2013 -0700 @@ -60,6 +60,7 @@ */ static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + @SuppressWarnings("raw") private static final Node EMPTY_NODE = new EmptyNode.OfRef(); private static final Node.OfInt EMPTY_INT_NODE = new EmptyNode.OfInt(); private static final Node.OfLong EMPTY_LONG_NODE = new EmptyNode.OfLong(); @@ -1786,6 +1787,10 @@ } } + /* + * This and subclasses are not intended to be serializable + */ + @SuppressWarnings("serial") private static abstract class SizedCollectorTask<P_IN, P_OUT, T_SINK extends Sink<P_OUT>, K extends SizedCollectorTask<P_IN, P_OUT, T_SINK, K>> extends CountedCompleter<Void> @@ -1855,6 +1860,7 @@ fence = (int) offset + (int) length; } + @SuppressWarnings("serial") static final class OfRef<P_IN, P_OUT> extends SizedCollectorTask<P_IN, P_OUT, Sink<P_OUT>, OfRef<P_IN, P_OUT>> implements Sink<P_OUT> { @@ -1886,6 +1892,7 @@ } } + @SuppressWarnings("serial") static final class OfInt<P_IN> extends SizedCollectorTask<P_IN, Integer, Sink.OfInt, OfInt<P_IN>> implements Sink.OfInt { @@ -1917,6 +1924,7 @@ } } + @SuppressWarnings("serial") static final class OfLong<P_IN> extends SizedCollectorTask<P_IN, Long, Sink.OfLong, OfLong<P_IN>> implements Sink.OfLong { @@ -1948,6 +1956,7 @@ } } + @SuppressWarnings("serial") static final class OfDouble<P_IN> extends SizedCollectorTask<P_IN, Double, Sink.OfDouble, OfDouble<P_IN>> implements Sink.OfDouble { @@ -1980,6 +1989,7 @@ } } + @SuppressWarnings("serial") private static abstract class ToArrayTask<T, T_NODE extends Node<T>, K extends ToArrayTask<T, T_NODE, K>> extends CountedCompleter<Void> { @@ -2025,6 +2035,7 @@ } } + @SuppressWarnings("serial") private static final class OfRef<T> extends ToArrayTask<T, Node<T>, OfRef<T>> { private final T[] array; @@ -2050,6 +2061,7 @@ } } + @SuppressWarnings("serial") private static class OfPrimitive<T, T_CONS, T_ARR, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>, T_NODE extends Node.OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE>> @@ -2077,6 +2089,7 @@ } } + @SuppressWarnings("serial") private static final class OfInt extends OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, Node.OfInt> { private OfInt(Node.OfInt node, int[] array, int offset) { @@ -2084,6 +2097,7 @@ } } + @SuppressWarnings("serial") private static final class OfLong extends OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, Node.OfLong> { private OfLong(Node.OfLong node, long[] array, int offset) { @@ -2091,6 +2105,7 @@ } } + @SuppressWarnings("serial") private static final class OfDouble extends OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, Node.OfDouble> { private OfDouble(Node.OfDouble node, double[] array, int offset) { @@ -2099,6 +2114,7 @@ } } + @SuppressWarnings("serial") private static class CollectorTask<P_IN, P_OUT, T_NODE extends Node<P_OUT>, T_BUILDER extends Node.Builder<P_OUT>> extends AbstractTask<P_IN, P_OUT, T_NODE, CollectorTask<P_IN, P_OUT, T_NODE, T_BUILDER>> { protected final PipelineHelper<P_OUT> helper; @@ -2135,12 +2151,13 @@ } @Override - public void onCompletion(CountedCompleter caller) { + public void onCompletion(CountedCompleter<?> caller) { if (!isLeaf()) setLocalResult(concFactory.apply(leftChild.getLocalResult(), rightChild.getLocalResult())); super.onCompletion(caller); } + @SuppressWarnings("serial") private static final class OfRef<P_IN, P_OUT> extends CollectorTask<P_IN, P_OUT, Node<P_OUT>, Node.Builder<P_OUT>> { OfRef(PipelineHelper<P_OUT> helper, @@ -2150,6 +2167,7 @@ } } + @SuppressWarnings("serial") private static final class OfInt<P_IN> extends CollectorTask<P_IN, Integer, Node.OfInt, Node.Builder.OfInt> { OfInt(PipelineHelper<Integer> helper, Spliterator<P_IN> spliterator) { @@ -2157,6 +2175,7 @@ } } + @SuppressWarnings("serial") private static final class OfLong<P_IN> extends CollectorTask<P_IN, Long, Node.OfLong, Node.Builder.OfLong> { OfLong(PipelineHelper<Long> helper, Spliterator<P_IN> spliterator) { @@ -2164,6 +2183,7 @@ } } + @SuppressWarnings("serial") private static final class OfDouble<P_IN> extends CollectorTask<P_IN, Double, Node.OfDouble, Node.Builder.OfDouble> { OfDouble(PipelineHelper<Double> helper, Spliterator<P_IN> spliterator) {
--- a/src/share/classes/java/util/stream/ReduceOps.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/ReduceOps.java Wed Aug 07 19:56:20 2013 -0700 @@ -43,7 +43,7 @@ import java.util.function.Supplier; /** - * Factory for the creating instances of {@code TerminalOp) that implement + * Factory for creating instances of {@code TerminalOp} that implement * reductions. * * @since 1.8 @@ -148,17 +148,17 @@ * reference values. * * @param <T> the type of the input elements - * @param <R> the type of the result + * @param <I> the type of the intermediate reduction result * @param collector a {@code Collector} defining the reduction * @return a {@code ReduceOp} implementing the reduction */ - public static <T,R> TerminalOp<T, R> - makeRef(Collector<? super T,R> collector) { - Supplier<R> supplier = Objects.requireNonNull(collector).resultSupplier(); - BiFunction<R, ? super T, R> accumulator = collector.accumulator(); - BinaryOperator<R> combiner = collector.combiner(); - class ReducingSink extends Box<R> - implements AccumulatingSink<T, R, ReducingSink> { + public static <T, I> TerminalOp<T, I> + makeRef(Collector<? super T, I, ?> collector) { + Supplier<I> supplier = Objects.requireNonNull(collector).supplier(); + BiConsumer<I, ? super T> accumulator = collector.accumulator(); + BinaryOperator<I> combiner = collector.combiner(); + class ReducingSink extends Box<I> + implements AccumulatingSink<T, I, ReducingSink> { @Override public void begin(long size) { state = supplier.get(); @@ -166,9 +166,7 @@ @Override public void accept(T t) { - R newResult = accumulator.apply(state, t); - if (state != newResult) - state = newResult; + accumulator.accept(state, t); } @Override @@ -176,7 +174,7 @@ state = combiner.apply(state, other.state); } } - return new ReduceOp<T, R, ReducingSink>(StreamShape.REFERENCE) { + return new ReduceOp<T, I, ReducingSink>(StreamShape.REFERENCE) { @Override public ReducingSink makeSink() { return new ReducingSink(); @@ -720,6 +718,7 @@ /** * A {@code ForkJoinTask} for performing a parallel reduce operation. */ + @SuppressWarnings("serial") private static final class ReduceTask<P_IN, P_OUT, R, S extends AccumulatingSink<P_OUT, R, S>> extends AbstractTask<P_IN, P_OUT, S, ReduceTask<P_IN, P_OUT, R, S>> { @@ -749,7 +748,7 @@ } @Override - public void onCompletion(CountedCompleter caller) { + public void onCompletion(CountedCompleter<?> caller) { if (!isLeaf()) { S leftResult = leftChild.getLocalResult(); leftResult.combine(rightChild.getLocalResult());
--- a/src/share/classes/java/util/stream/ReferencePipeline.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/ReferencePipeline.java Wed Aug 07 19:56:20 2013 -0700 @@ -170,9 +170,10 @@ } @Override + @SuppressWarnings("unchecked") public void accept(P_OUT u) { if (predicate.test(u)) - downstream.accept(u); + downstream.accept((Object) u); } }; } @@ -180,6 +181,7 @@ } @Override + @SuppressWarnings("unchecked") public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) { Objects.requireNonNull(mapper); return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE, @@ -262,6 +264,7 @@ } @Override + @SuppressWarnings("unchecked") public void accept(P_OUT u) { // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it Stream<? extends R> result = mapper.apply(u); @@ -363,6 +366,7 @@ Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) { return new Sink.ChainedReference<P_OUT>(sink) { @Override + @SuppressWarnings("unchecked") public void accept(P_OUT u) { tee.accept(u); downstream.accept(u); @@ -439,6 +443,7 @@ // The runtime type of U is never checked for equality with the component type of the runtime type of A[]. // Runtime checking will be performed when an element is stored in A[], thus if A is not a // super type of U an ArrayStoreException will be thrown. + @SuppressWarnings("rawtypes") IntFunction rawGenerator = (IntFunction) generator; return (A[]) Nodes.flatten(evaluateToArrayNode(rawGenerator), rawGenerator) .asArray(rawGenerator); @@ -490,16 +495,21 @@ } @Override - public final <R> R collect(Collector<? super P_OUT, R> collector) { + public final <R, A> R collect(Collector<? super P_OUT, A, ? extends R> collector) { + A container; if (isParallel() && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT)) && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) { - R container = collector.resultSupplier().get(); - BiFunction<R, ? super P_OUT, R> accumulator = collector.accumulator(); - forEach(u -> accumulator.apply(container, u)); - return container; + container = collector.supplier().get(); + BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator(); + forEach(u -> accumulator.accept(container, u)); } - return evaluate(ReduceOps.makeRef(collector)); + else { + container = evaluate(ReduceOps.makeRef(collector)); + } + return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH) + ? (R) container + : collector.finisher().apply(container); } @Override
--- a/src/share/classes/java/util/stream/Sink.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/Sink.java Wed Aug 07 19:56:20 2013 -0700 @@ -242,6 +242,7 @@ * {@code accept()} method on the downstream {@code Sink}. */ static abstract class ChainedReference<T> implements Sink<T> { + @SuppressWarnings("rawtypes") protected final Sink downstream; public ChainedReference(Sink downstream) { @@ -274,6 +275,7 @@ * {@code accept()} method on the downstream {@code Sink}. */ static abstract class ChainedInt implements Sink.OfInt { + @SuppressWarnings("rawtypes") protected final Sink downstream; public ChainedInt(Sink downstream) { @@ -306,6 +308,7 @@ * {@code accept()} method on the downstream {@code Sink}. */ static abstract class ChainedLong implements Sink.OfLong { + @SuppressWarnings("rawtypes") protected final Sink downstream; public ChainedLong(Sink downstream) { @@ -338,6 +341,7 @@ * {@code accept()} method on the downstream {@code Sink}. */ static abstract class ChainedDouble implements Sink.OfDouble { + @SuppressWarnings("rawtypes") protected final Sink downstream; public ChainedDouble(Sink downstream) {
--- a/src/share/classes/java/util/stream/SliceOps.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/SliceOps.java Wed Aug 07 19:56:20 2013 -0700 @@ -550,6 +550,7 @@ * @param <P_IN> Input element type to the stream pipeline * @param <P_OUT> Output element type from the stream pipeline */ + @SuppressWarnings("serial") private static final class SliceTask<P_IN, P_OUT> extends AbstractShortCircuitTask<P_IN, P_OUT, Node<P_OUT>, SliceTask<P_IN, P_OUT>> { private final AbstractPipeline<P_OUT, P_OUT, ?> op;
--- a/src/share/classes/java/util/stream/SortedOps.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/SortedOps.java Wed Aug 07 19:56:20 2013 -0700 @@ -209,7 +209,7 @@ } @Override - public Sink<Long> opWrapSink(int flags, Sink sink) { + public Sink<Long> opWrapSink(int flags, Sink<Long> sink) { Objects.requireNonNull(sink); if (StreamOpFlag.SORTED.isKnown(flags)) @@ -248,7 +248,7 @@ } @Override - public Sink<Double> opWrapSink(int flags, Sink sink) { + public Sink<Double> opWrapSink(int flags, Sink<Double> sink) { Objects.requireNonNull(sink); if (StreamOpFlag.SORTED.isKnown(flags)) @@ -285,7 +285,7 @@ private T[] array; private int offset; - SizedRefSortingSink(Sink sink, Comparator<? super T> comparator) { + SizedRefSortingSink(Sink<T> sink, Comparator<? super T> comparator) { super(sink); this.comparator = comparator; } @@ -324,7 +324,7 @@ private final Comparator<? super T> comparator; private ArrayList<T> list; - RefSortingSink(Sink sink, Comparator<? super T> comparator) { + RefSortingSink(Sink<T> sink, Comparator<? super T> comparator) { super(sink); this.comparator = comparator; }
--- a/src/share/classes/java/util/stream/SpinedBuffer.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/SpinedBuffer.java Wed Aug 07 19:56:20 2013 -0700 @@ -28,6 +28,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; @@ -317,6 +318,8 @@ @Override public boolean tryAdvance(Consumer<? super E> consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { consumer.accept(splChunk[splElementIndex++]); @@ -334,6 +337,8 @@ @Override public void forEachRemaining(Consumer<? super E> consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { int i = splElementIndex; @@ -634,6 +639,8 @@ @Override public boolean tryAdvance(T_CONS consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { arrayForOne(splChunk, splElementIndex++, consumer); @@ -651,6 +658,8 @@ @Override public void forEachRemaining(T_CONS consumer) { + Objects.requireNonNull(consumer); + if (splSpineIndex < lastSpineIndex || (splSpineIndex == lastSpineIndex && splElementIndex < lastSpineElementFence)) { int i = splElementIndex;
--- a/src/share/classes/java/util/stream/Stream.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/Stream.java Wed Aug 07 19:56:20 2013 -0700 @@ -651,12 +651,13 @@ * }</pre> * * @param <R> the type of the result + * @param <A> the intermediate accumulation type of the {@code Collector} * @param collector the {@code Collector} describing the reduction * @return the result of the reduction * @see #collect(Supplier, BiConsumer, BiConsumer) * @see Collectors */ - <R> R collect(Collector<? super T, R> collector); + <R, A> R collect(Collector<? super T, A, ? extends R> collector); /** * Returns the minimum element of this stream according to the provided @@ -827,6 +828,7 @@ * @return the new stream */ @SafeVarargs + @SuppressWarnings("varargs") // Creating a stream from an array is safe public static<T> Stream<T> of(T... values) { return Arrays.stream(values); }
--- a/src/share/classes/java/util/stream/StreamSpliterators.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/StreamSpliterators.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,6 +25,7 @@ package java.util.stream; import java.util.Comparator; +import java.util.Objects; import java.util.Spliterator; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BooleanSupplier; @@ -294,6 +295,7 @@ @Override public boolean tryAdvance(Consumer<? super P_OUT> consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -303,6 +305,7 @@ @Override public void forEachRemaining(Consumer<? super P_OUT> consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator); @@ -350,6 +353,7 @@ @Override public boolean tryAdvance(IntConsumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -359,6 +363,7 @@ @Override public void forEachRemaining(IntConsumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink.OfInt) consumer::accept, spliterator); @@ -406,6 +411,7 @@ @Override public boolean tryAdvance(LongConsumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -415,6 +421,7 @@ @Override public void forEachRemaining(LongConsumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink.OfLong) consumer::accept, spliterator); @@ -462,6 +469,7 @@ @Override public boolean tryAdvance(DoubleConsumer consumer) { + Objects.requireNonNull(consumer); boolean hasNext = doAdvance(); if (hasNext) consumer.accept(buffer.get(nextToConsume)); @@ -471,6 +479,7 @@ @Override public void forEachRemaining(DoubleConsumer consumer) { if (buffer == null && !finished) { + Objects.requireNonNull(consumer); init(); ph.wrapAndCopyInto((Sink.OfDouble) consumer::accept, spliterator); @@ -696,6 +705,8 @@ @Override public boolean tryAdvance(Consumer<? super T> action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return false; @@ -713,6 +724,8 @@ @Override public void forEachRemaining(Consumer<? super T> action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return; @@ -754,6 +767,8 @@ @Override public boolean tryAdvance(T_CONS action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return false; @@ -771,6 +786,8 @@ @Override public void forEachRemaining(T_CONS action) { + Objects.requireNonNull(action); + if (sliceOrigin >= fence) return; @@ -895,7 +912,8 @@ this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip); } - UnorderedSliceSpliterator(T_SPLITR s, UnorderedSliceSpliterator parent) { + UnorderedSliceSpliterator(T_SPLITR s, + UnorderedSliceSpliterator<T, T_SPLITR> parent) { this.s = s; this.unlimited = parent.unlimited; this.permits = parent.permits; @@ -974,7 +992,7 @@ super(s, skip, limit); } - OfRef(Spliterator<T> s, OfRef parent) { + OfRef(Spliterator<T> s, OfRef<T> parent) { super(s, parent); } @@ -985,6 +1003,8 @@ @Override public boolean tryAdvance(Consumer<? super T> action) { + Objects.requireNonNull(action); + while (permitStatus() != PermitStatus.NO_MORE) { if (!s.tryAdvance(this)) return false; @@ -999,6 +1019,8 @@ @Override public void forEachRemaining(Consumer<? super T> action) { + Objects.requireNonNull(action); + ArrayBuffer.OfRef<T> sb = null; PermitStatus permitStatus; while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { @@ -1051,6 +1073,8 @@ @Override public boolean tryAdvance(T_CONS action) { + Objects.requireNonNull(action); + while (permitStatus() != PermitStatus.NO_MORE) { if (!s.tryAdvance((T_CONS) this)) return false; @@ -1066,6 +1090,8 @@ @Override public void forEachRemaining(T_CONS action) { + Objects.requireNonNull(action); + T_BUFF sb = null; PermitStatus permitStatus; while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { @@ -1237,6 +1263,8 @@ @Override public boolean tryAdvance(Consumer<? super T> action) { + Objects.requireNonNull(action); + action.accept(s.get()); return true; } @@ -1260,6 +1288,8 @@ @Override public boolean tryAdvance(IntConsumer action) { + Objects.requireNonNull(action); + action.accept(s.getAsInt()); return true; } @@ -1283,6 +1313,8 @@ @Override public boolean tryAdvance(LongConsumer action) { + Objects.requireNonNull(action); + action.accept(s.getAsLong()); return true; } @@ -1306,6 +1338,8 @@ @Override public boolean tryAdvance(DoubleConsumer action) { + Objects.requireNonNull(action); + action.accept(s.getAsDouble()); return true; }
--- a/src/share/classes/java/util/stream/Streams.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/Streams.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,6 +25,7 @@ package java.util.stream; import java.util.Comparator; +import java.util.Objects; import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.DoubleConsumer; @@ -80,6 +81,8 @@ @Override public boolean tryAdvance(IntConsumer consumer) { + Objects.requireNonNull(consumer); + final int i = from; if (i < upTo) { from++; @@ -96,6 +99,8 @@ @Override public void forEachRemaining(IntConsumer consumer) { + Objects.requireNonNull(consumer); + int i = from; final int hUpTo = upTo; int hLast = last; @@ -199,6 +204,8 @@ @Override public boolean tryAdvance(LongConsumer consumer) { + Objects.requireNonNull(consumer); + final long i = from; if (i < upTo) { from++; @@ -215,6 +222,8 @@ @Override public void forEachRemaining(LongConsumer consumer) { + Objects.requireNonNull(consumer); + long i = from; final long hUpTo = upTo; int hLast = last; @@ -388,6 +397,8 @@ @Override public boolean tryAdvance(Consumer<? super T> action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -400,6 +411,8 @@ @Override public void forEachRemaining(Consumer<? super T> action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -475,6 +488,8 @@ @Override public boolean tryAdvance(IntConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -487,6 +502,8 @@ @Override public void forEachRemaining(IntConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -562,6 +579,8 @@ @Override public boolean tryAdvance(LongConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -574,6 +593,8 @@ @Override public void forEachRemaining(LongConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -649,6 +670,8 @@ @Override public boolean tryAdvance(DoubleConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1; @@ -661,6 +684,8 @@ @Override public void forEachRemaining(DoubleConsumer action) { + Objects.requireNonNull(action); + if (count == -2) { action.accept(first); count = -1;
--- a/src/share/classes/java/util/stream/package-info.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/java/util/stream/package-info.java Wed Aug 07 19:56:20 2013 -0700 @@ -547,7 +547,7 @@ * List<String> l = new ArrayList(Arrays.asList("one", "two")); * Stream<String> sl = l.stream(); * l.add("three"); - * String s = sl.collect(toStringJoiner(" ")).toString(); + * String s = sl.collect(joining(" ")); * }</pre> * First a list is created consisting of two strings: "one"; and "two". Then a stream is created from that list. * Next the list is modified by adding a third string: "three". Finally the elements of the stream are collected @@ -557,7 +557,7 @@ * <pre>{@code * List<String> l = new ArrayList(Arrays.asList("one", "two")); * Stream<String> sl = l.stream(); - * String s = sl.peek(s -> l.add("BAD LAMBDA")).collect(toStringJoiner(" ")).toString(); + * String s = sl.peek(s -> l.add("BAD LAMBDA")).collect(joining(" ")); * }</pre> * then a {@code ConcurrentModificationException} will be thrown since the {@code peek} operation will attempt * to add the string "BAD LAMBDA" to the list after the terminal operation has commenced.
--- a/src/share/classes/javax/accessibility/Accessible.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/Accessible.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -45,6 +45,7 @@ * of an object that implements Accessible, and that subclass * is not Accessible, the developer should override the * getAccessibleContext method to return null. + * @return the AccessibleContext associated with this object */ public AccessibleContext getAccessibleContext(); }
--- a/src/share/classes/javax/accessibility/AccessibleBundle.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleBundle.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -53,6 +53,9 @@ private final String defaultResourceBundleName = "com.sun.accessibility.internal.resources.accessibility"; + /** + * Construct an {@code AccessibleBundle}. + */ public AccessibleBundle() { }
--- a/src/share/classes/javax/accessibility/AccessibleExtendedTable.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleExtendedTable.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -60,7 +60,7 @@ */ public int getAccessibleColumn(int index); - /* + /** * Returns the index at a row and column in the table. * * @param r zero-based row of the table
--- a/src/share/classes/javax/accessibility/AccessibleRelationSet.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleRelationSet.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -163,6 +163,7 @@ /** * Returns the number of relations in the relation set. + * @return the number of relations in the relation set */ public int size() { if (relations == null) {
--- a/src/share/classes/javax/accessibility/AccessibleTable.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleTable.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -90,6 +90,8 @@ * Returns the number of rows occupied by the Accessible at * a specified row and column in the table. * + * @param r zero-based row of the table + * @param c zero-based column of the table * @return the number of rows occupied by the Accessible at a * given specified (row, column) */ @@ -99,6 +101,8 @@ * Returns the number of columns occupied by the Accessible at * a specified row and column in the table. * + * @param r zero-based row of the table + * @param c zero-based column of the table * @return the number of columns occupied by the Accessible at a * given specified row and column */
--- a/src/share/classes/javax/accessibility/AccessibleTableModelChange.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleTableModelChange.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,8 +71,8 @@ public static final int DELETE = -1; /** - * Returns the type of event - * + * Returns the type of event. + * @return the type of event * @see #INSERT * @see #UPDATE * @see #DELETE @@ -81,21 +81,25 @@ /** * Returns the first row that changed. + * @return the first row that changed */ public int getFirstRow(); /** * Returns the last row that changed. + * @return the last row that changed */ public int getLastRow(); /** * Returns the first column that changed. + * @return the first column that changed */ public int getFirstColumn(); /** * Returns the last column that changed. + * @return the last column that changed */ public int getLastColumn(); }
--- a/src/share/classes/javax/accessibility/AccessibleTextSequence.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleTextSequence.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ */ public class AccessibleTextSequence { - /* The start index of the text sequence */ + /** The start index of the text sequence */ public int startIndex; /** The end index of the text sequence */
--- a/src/share/classes/javax/accessibility/AccessibleValue.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/accessibility/AccessibleValue.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -60,6 +60,7 @@ /** * Set the value of this object as a Number. * + * @param n the number to use for the value * @return True if the value was set; else False * @see #getCurrentAccessibleValue */
--- a/src/share/classes/javax/management/relation/RelationNotification.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/management/relation/RelationNotification.java Wed Aug 07 19:56:20 2013 -0700 @@ -260,7 +260,7 @@ super(notifType, sourceObj, sequence, timeStamp, message); - if (!isValidBasic(notifType,sourceObj,id,typeName) || !isValidCreate(notifType)) { + if (!isValidBasicStrict(notifType,sourceObj,id,typeName) || !isValidCreate(notifType)) { throw new IllegalArgumentException("Invalid parameter."); } @@ -310,7 +310,7 @@ super(notifType, sourceObj, sequence, timeStamp, message); - if (!isValidBasic(notifType,sourceObj,id,typeName) || !isValidUpdate(notifType,name,newValue,oldValue)) { + if (!isValidBasicStrict(notifType,sourceObj,id,typeName) || !isValidUpdate(notifType,name,newValue,oldValue)) { throw new IllegalArgumentException("Invalid parameter."); } @@ -457,14 +457,26 @@ // - no role old value (for role update) // - no role new value (for role update) + // Despite the fact, that validation in constructor of RelationNotification prohibit + // creation of the class instance with null sourceObj its possible to set it to null later + // by public setSource() method. + // So we should relax validation rules to preserve serialization behavior compatibility. + + private boolean isValidBasicStrict(String notifType, Object sourceObj, String id, String typeName){ + if (sourceObj == null) { + return false; + } + return isValidBasic(notifType,sourceObj,id,typeName); + } + private boolean isValidBasic(String notifType, Object sourceObj, String id, String typeName){ - if (notifType == null || sourceObj == null || - id == null || typeName == null) { + if (notifType == null || id == null || typeName == null) { return false; } - if (!(sourceObj instanceof RelationService) && - !(sourceObj instanceof ObjectName)) { + if (sourceObj != null && ( + !(sourceObj instanceof RelationService) && + !(sourceObj instanceof ObjectName))) { return false; }
--- a/src/share/classes/javax/sound/midi/MetaMessage.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MetaMessage.java Wed Aug 07 19:56:20 2013 -0700 @@ -149,7 +149,7 @@ * @param data the data bytes in the MIDI message * @param length the number of bytes in the <code>data</code> * byte array - * @throws <code>InvalidMidiDataException</code> if the + * @throws InvalidMidiDataException if the * parameter values do not specify a valid MIDI meta message */ public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException {
--- a/src/share/classes/javax/sound/midi/MidiDevice.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MidiDevice.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -86,13 +86,13 @@ * To detect if a MidiDevice represents a hardware MIDI port, the * following programming technique can be used: * - * <pre> + * <pre>{@code * MidiDevice device = ...; * if ( ! (device instanceof Sequencer) && ! (device instanceof Synthesizer)) { * // we're now sure that device represents a MIDI port * // ... * } - * </pre> + * }</pre> * * <p> * A <code>MidiDevice</code> includes a <code>{@link MidiDevice.Info}</code> object
--- a/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -33,7 +33,9 @@ * @since 1.7 */ public interface MidiDeviceReceiver extends Receiver { - /** Obtains a MidiDevice object which is an owner of this Receiver. + /** + * Obtains a MidiDevice object which is an owner of this Receiver. + * @return a MidiDevice object which is an owner of this Receiver */ public MidiDevice getMidiDevice(); }
--- a/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,9 @@ */ public interface MidiDeviceTransmitter extends Transmitter { - /** Obtains a MidiDevice object which is an owner of this Transmitter. + /** + * Obtains a MidiDevice object which is an owner of this Transmitter. + * @return a MidiDevice object which is an owner of this Transmitter */ public MidiDevice getMidiDevice(); }
--- a/src/share/classes/javax/sound/midi/MidiFileFormat.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MidiFileFormat.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,7 @@ * be used in implementations: * * <table border=1> + <caption>MIDI File Format Properties</caption> * <tr> * <th>Property key</th> * <th>Value type</th>
--- a/src/share/classes/javax/sound/midi/MidiMessage.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MidiMessage.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -55,7 +55,7 @@ * processing MIDI data that originated outside Java Sound and now * is encoded as signed bytes, the bytes can * can be converted to integers using this conversion: - * <center><code>int i = (int)(byte & 0xFF)</code></center> + * <center>{@code int i = (int)(byte & 0xFF)}</center> * <p> * If you simply need to pass a known MIDI byte value as a method parameter, * it can be expressed directly as an integer, using (for example) decimal or @@ -118,6 +118,10 @@ * method is called by concrete subclasses, which should * ensure that the data array specifies a complete, valid MIDI * message. + * + * @param data the data bytes in the MIDI message + * @param length the number of bytes in the data byte array + * @throws InvalidMidiDataException if the parameter values do not specify a valid MIDI meta message */ protected void setMessage(byte[] data, int length) throws InvalidMidiDataException { if (length < 0 || (length > 0 && length > data.length)) {
--- a/src/share/classes/javax/sound/midi/MidiSystem.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/MidiSystem.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -80,6 +80,7 @@ * consider them: * * <table border=0> + * <caption>MIDI System Property Keys</caption> * <tr> * <th>Property Key</th> * <th>Interface</th> @@ -425,6 +426,8 @@ * it is used to identify the default sequencer. * For details, refer to the {@link MidiSystem class description}. * + * @param connected whether or not the returned {@code Sequencer} + * is connected to the default {@code Synthesizer} * @return the default sequencer * @throws MidiUnavailableException if the sequencer is not * available due to resource restrictions,
--- a/src/share/classes/javax/sound/midi/ShortMessage.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/ShortMessage.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -283,7 +283,7 @@ /** * Sets the parameters for a MIDI message that takes no data bytes. * @param status the MIDI status byte - * @throws <code>InvalidMidiDataException</code> if <code>status</code> does not + * @throws InvalidMidiDataException if <code>status</code> does not * specify a valid MIDI status byte for a message that requires no data bytes. * @see #setMessage(int, int, int) * @see #setMessage(int, int, int, int) @@ -307,7 +307,7 @@ * @param status the MIDI status byte * @param data1 the first data byte * @param data2 the second data byte - * @throws <code>InvalidMidiDataException</code> if the + * @throws InvalidMidiDataException if the * the status byte, or all data bytes belonging to the message, do * not specify a valid MIDI message. * @see #setMessage(int, int, int, int) @@ -357,7 +357,7 @@ * @param channel the channel associated with the message * @param data1 the first data byte * @param data2 the second data byte - * @throws <code>InvalidMidiDataException</code> if the + * @throws InvalidMidiDataException if the * status byte or all data bytes belonging to the message, do * not specify a valid MIDI message * @@ -397,6 +397,7 @@ * Obtains the MIDI command associated with this event. This method * assumes that the event is a MIDI channel message; if not, the return * value will not be meaningful. + * @return the MIDI command associated with this event * @see #setMessage(int, int, int, int) */ public int getCommand() { @@ -450,7 +451,7 @@ * status byte value. * @param status status byte value, which must represent a short MIDI message * @return data length in bytes (0, 1, or 2) - * @throws <code>InvalidMidiDataException</code> if the + * @throws InvalidMidiDataException if the * <code>status</code> argument does not represent the status byte for any * short message */
--- a/src/share/classes/javax/sound/midi/Synthesizer.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/Synthesizer.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -170,7 +170,7 @@ * already had been), <code>false</code> if the instrument could not be * loaded (for example, if the synthesizer has insufficient * memory to load it) - * @throws <code>IllegalArgumentException</code> if this + * @throws IllegalArgumentException if this * <code>Synthesizer</code> doesn't support the specified instrument's * soundbank * @see #unloadInstrument @@ -186,7 +186,7 @@ /** * Unloads a particular instrument. * @param instrument instrument to unload - * @throws <code>IllegalArgumentException</code> if this + * @throws IllegalArgumentException if this * <code>Synthesizer</code> doesn't support the specified instrument's * soundbank * @see #loadInstrument @@ -214,10 +214,10 @@ * of the old instrument, it should be loaded into the synthesizer * @return <code>true</code> if the instrument succeessfully remapped, * <code>false</code> if feature is not implemented by synthesizer - * @throws <code>IllegalArgumentException</code> if instrument + * @throws IllegalArgumentException if instrument * <code>from</code> or instrument <code>to</code> aren't supported by * synthesizer or if instrument <code>to</code> is not loaded - * @throws <code>NullPointerException</code> if <code>from</code> or + * @throws NullPointerException if <code>from</code> or * <code>to</code> parameters have null value * @see #loadInstrument * @see #loadInstruments
--- a/src/share/classes/javax/sound/midi/SysexMessage.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/SysexMessage.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -204,6 +204,7 @@ * @param data the system exclusive message data * @param length the length of the valid message data in * the array + * @throws InvalidMidiDataException if the status byte is invalid for a sysex message */ public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException { if ( (status != 0xF0) && (status != 0xF7) ) {
--- a/src/share/classes/javax/sound/midi/Track.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/midi/Track.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -211,10 +211,11 @@ /** * Obtains the event at the specified index. * @param index the location of the desired event in the event vector - * @throws <code>ArrayIndexOutOfBoundsException</code> if the + * @throws ArrayIndexOutOfBoundsException if the * specified index is negative or not less than the current size of * this track. * @see #size + * @return the event at the specified index */ public MidiEvent get(int index) throws ArrayIndexOutOfBoundsException { try {
--- a/src/share/classes/javax/sound/sampled/AudioFileFormat.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/sampled/AudioFileFormat.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -57,6 +57,7 @@ * be used in implementations: * * <table border=1> + * <caption>Audio File Format Property Keys</caption> * <tr> * <th>Property key</th> * <th>Value type</th>
--- a/src/share/classes/javax/sound/sampled/AudioFormat.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/sampled/AudioFormat.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,6 +85,7 @@ * service providers should use, if applicable: * * <table border=0> + * <caption>Audio Format Property Keys</caption> * <tr> * <th>Property key</th> * <th>Value type</th>
--- a/src/share/classes/javax/sound/sampled/AudioSystem.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/sampled/AudioSystem.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -75,6 +75,7 @@ * consider them: * * <table border=0> + * <caption>Audio System Property Keys</caption> * <tr> * <th>Property Key</th> * <th>Interface</th>
--- a/src/share/classes/javax/sound/sampled/BooleanControl.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/sampled/BooleanControl.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -125,6 +125,7 @@ /** * Obtains the label for the specified state. + * @param state the state whose label will be returned * @return the label for the specified state, such as "true" or "on" * for <code>true</code>, or "false" or "off" for <code>false</code>. */
--- a/src/share/classes/javax/sound/sampled/Mixer.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/sampled/Mixer.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -133,6 +133,8 @@ * <code>DataLine</code>. * * @param info describes the desired line + * @return a line that is available for use and that matches the description + * in the specified {@code Line.Info} object * @throws LineUnavailableException if a matching line * is not available due to resource restrictions * @throws IllegalArgumentException if this mixer does
--- a/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -116,6 +116,7 @@ * given a particular source format. * If no target format encodings are supported for this source format, * an array of length 0 is returned. + * @param sourceFormat format of the incoming data * @return array of supported target format encodings. */ public abstract AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat); @@ -146,6 +147,8 @@ * supported by the format converter * If no target formats with the specified encoding are supported * for this source format, an array of length 0 is returned. + * @param targetEncoding desired encoding of the stream after processing + * @param sourceFormat format of the incoming data * @return array of supported target formats. */ public abstract AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat);
--- a/src/share/classes/javax/swing/SwingWorker.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/javax/swing/SwingWorker.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -405,6 +405,7 @@ * */ @SafeVarargs + @SuppressWarnings("varargs") // Passing chunks to add is safe protected final void publish(V... chunks) { synchronized (this) { if (doProcess == null) {
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java Wed Aug 07 19:56:20 2013 -0700 @@ -75,7 +75,10 @@ throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element) @@ -90,7 +93,10 @@ throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element)
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java Wed Aug 07 19:56:20 2013 -0700 @@ -76,7 +76,10 @@ throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element) @@ -91,7 +94,10 @@ throw new ClassCastException ("context must be of type DOMCryptoContext"); } - if (parent == null || !(parent instanceof javax.xml.crypto.dom.DOMStructure)) { + if (parent == null) { + throw new NullPointerException(); + } + if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { throw new ClassCastException("parent must be of type DOMStructure"); } transformElem = (Element)
--- a/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/invoke/anon/ConstantPoolPatch.java Wed Aug 07 19:56:20 2013 -0700 @@ -418,7 +418,7 @@ private static final Map<Class<?>, Byte> CONSTANT_VALUE_CLASS_TAG = new IdentityHashMap<Class<?>, Byte>(); - private static final Class[] CONSTANT_VALUE_CLASS = new Class[16]; + private static final Class<?>[] CONSTANT_VALUE_CLASS = new Class<?>[16]; static { Object[][] values = { {Integer.class, CONSTANT_Integer},
--- a/src/share/classes/sun/net/www/protocol/http/AuthCacheValue.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/net/www/protocol/http/AuthCacheValue.java Wed Aug 07 19:56:20 2013 -0700 @@ -37,6 +37,8 @@ public abstract class AuthCacheValue implements Serializable { + static final long serialVersionUID = 735249334068211611L; + public enum Type { Proxy, Server
--- a/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java Wed Aug 07 19:56:20 2013 -0700 @@ -51,6 +51,8 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Cloneable { + static final long serialVersionUID = -2588378268010453259L; + // Constants saying what kind of authroization this is. This determines // the namespace in the hash table lookup. public static final char SERVER_AUTHENTICATION = 's';
--- a/src/share/classes/sun/reflect/annotation/AnnotationParser.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/reflect/annotation/AnnotationParser.java Wed Aug 07 19:56:20 2013 -0700 @@ -88,6 +88,7 @@ * @param selectAnnotationClasses an array of annotation types to select when parsing */ @SafeVarargs + @SuppressWarnings("varargs") // selectAnnotationClasses is used safely static Map<Class<? extends Annotation>, Annotation> parseSelectAnnotations( byte[] rawAnnotations, ConstantPool constPool,
--- a/src/share/classes/sun/rmi/runtime/Log.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/runtime/Log.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -61,6 +61,7 @@ * @author Laird Dornin * @since 1.4 */ +@SuppressWarnings("deprecation") public abstract class Log { /** Logger re-definition of old RMI log values */
--- a/src/share/classes/sun/rmi/server/ActivatableRef.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/server/ActivatableRef.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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,6 +41,7 @@ import java.rmi.server.RemoteRef; import java.rmi.server.RemoteStub; +@SuppressWarnings("deprecation") public class ActivatableRef implements RemoteRef { private static final long serialVersionUID = 7579060052569229166L;
--- a/src/share/classes/sun/rmi/server/Dispatcher.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/server/Dispatcher.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ * The Dispatcher interface allows the transport to make * the upcall to the server side remote reference. */ +@SuppressWarnings("deprecation") public interface Dispatcher { /**
--- a/src/share/classes/sun/rmi/server/LoaderHandler.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/server/LoaderHandler.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -67,6 +67,7 @@ * @author Peter Jones * @author Laird Dornin */ +@SuppressWarnings("deprecation") public final class LoaderHandler { /** RMI class loader log level */
--- a/src/share/classes/sun/rmi/server/UnicastRef.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/server/UnicastRef.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,8 @@ * NOTE: There is a JDK-internal dependency on the existence of this * class's getLiveRef method (as it is inherited by UnicastRef2) in * the implementation of javax.management.remote.rmi.RMIConnector. - **/ + */ +@SuppressWarnings("deprecation") public class UnicastRef implements RemoteRef { /**
--- a/src/share/classes/sun/rmi/server/UnicastServerRef.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/server/UnicastServerRef.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -67,6 +67,7 @@ * @author Roger Riggs * @author Peter Jones */ +@SuppressWarnings("deprecation") public class UnicastServerRef extends UnicastRef implements ServerRef, Dispatcher {
--- a/src/share/classes/sun/rmi/server/Util.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/server/Util.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -64,6 +64,7 @@ * A utility class with static methods for creating stubs/proxies and * skeletons for remote objects. */ +@SuppressWarnings("deprecation") public final class Util { /** "server" package log level */
--- a/src/share/classes/sun/rmi/transport/DGCImpl.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/transport/DGCImpl.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,7 @@ * * @author Ann Wollrath */ +@SuppressWarnings("deprecation") final class DGCImpl implements DGC { /* dgc system log */
--- a/src/share/classes/sun/rmi/transport/StreamRemoteCall.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/transport/StreamRemoteCall.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -45,6 +45,7 @@ * * @author Ann Wollrath */ +@SuppressWarnings("deprecation") public class StreamRemoteCall implements RemoteCall { private ConnectionInputStream in = null; private ConnectionOutputStream out = null;
--- a/src/share/classes/sun/rmi/transport/Transport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/transport/Transport.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ * * @author Ann Wollrath */ +@SuppressWarnings("deprecation") public abstract class Transport { /** "transport" package log level */
--- a/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -44,6 +44,7 @@ * connect to the same host will automatically use the same * mechanism. */ +@SuppressWarnings("deprecation") public class RMIMasterSocketFactory extends RMISocketFactory { /** "proxy" package log level */
--- a/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -43,6 +43,7 @@ * * @author Peter Jones */ +@SuppressWarnings("deprecation") final class ConnectionMultiplexer { /** "multiplex" log level */
--- a/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -84,6 +84,7 @@ * @author Ann Wollrath * @author Peter Jones */ +@SuppressWarnings("deprecation") public class TCPTransport extends Transport { /* tcp package log */
--- a/src/share/classes/sun/security/ec/ECDSASignature.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/security/ec/ECDSASignature.java Wed Aug 07 19:56:20 2013 -0700 @@ -323,6 +323,7 @@ // set parameter, not supported. See JCA doc @Override + @Deprecated protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new UnsupportedOperationException("setParameter() not supported"); @@ -330,6 +331,7 @@ // get parameter, not supported. See JCA doc @Override + @Deprecated protected Object engineGetParameter(String param) throws InvalidParameterException { throw new UnsupportedOperationException("getParameter() not supported");
--- a/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,10 +96,15 @@ } } - // SecretKeySpec does not allow zero length keys, so we define our own class. + // SecretKeySpec does not allow zero length keys, so we define our + // own class. + // + // As an anonymous class cannot make any guarantees about serialization + // compatibility, it is nonsensical for an anonymous class to define a + // serialVersionUID. Suppress warnings relative to missing serialVersionUID + // field in the anonymous subclass of serializable SecretKey. + @SuppressWarnings("serial") private static final SecretKey NULL_KEY = new SecretKey() { - private static final long serialVersionUID = -8090049519656411362L; - public byte[] getEncoded() { return new byte[0]; }
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Wed Aug 07 19:56:20 2013 -0700 @@ -775,7 +775,7 @@ } } if (params != null) { - if (algorithm.equals(pbes2_OID)) { + if (algorithm.equals((Object)pbes2_OID)) { algParams = AlgorithmParameters.getInstance("PBES2"); } else { algParams = AlgorithmParameters.getInstance("PBE"); @@ -912,7 +912,7 @@ private static String mapPBEParamsToAlgorithm(ObjectIdentifier algorithm, AlgorithmParameters algParams) throws NoSuchAlgorithmException { // Check for PBES2 algorithms - if (algorithm.equals(pbes2_OID) && algParams != null) { + if (algorithm.equals((Object)pbes2_OID) && algParams != null) { return algParams.toString(); } return algorithm.toString(); @@ -1921,7 +1921,7 @@ } safeContentsData = safeContents.getData(); - } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) { + } else if (contentType.equals((Object)ContentInfo.ENCRYPTED_DATA_OID)) { if (password == null) { continue; }
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Aug 07 19:56:20 2013 -0700 @@ -169,7 +169,7 @@ /* * Drives the protocol state machine. */ - private int connectionState; + private volatile int connectionState; /* * Flag indicating if the next record we receive MUST be a Finished @@ -1467,7 +1467,7 @@ */ @Override public boolean isClosed() { - return getConnectionState() == cs_APP_CLOSED; + return connectionState == cs_APP_CLOSED; } /**
--- a/src/share/classes/sun/security/tools/jarsigner/Main.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/security/tools/jarsigner/Main.java Wed Aug 07 19:56:20 2013 -0700 @@ -291,7 +291,8 @@ String flags = args[n]; String modifier = null; - if (flags.charAt(0) == '-') { + + if (flags.startsWith("-")) { int pos = flags.indexOf(':'); if (pos > 0) { modifier = flags.substring(pos+1); @@ -299,7 +300,14 @@ } } - if (collator.compare(flags, "-keystore") == 0) { + if (!flags.startsWith("-")) { + if (jarfile == null) { + jarfile = flags; + } else { + alias = flags; + ckaliases.add(alias); + } + } else if (collator.compare(flags, "-keystore") == 0) { if (++n == args.length) usageNoArg(); keystore = args[n]; } else if (collator.compare(flags, "-storepass") ==0) { @@ -380,18 +388,9 @@ collator.compare(flags, "-help") == 0) { fullusage(); } else { - if (!flags.startsWith("-")) { - if (jarfile == null) { - jarfile = flags; - } else { - alias = flags; - ckaliases.add(alias); - } - } else { - System.err.println( - rb.getString("Illegal.option.") + flags); - usage(); - } + System.err.println( + rb.getString("Illegal.option.") + flags); + usage(); } }
--- a/src/share/classes/sun/swing/AccumulativeRunnable.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/swing/AccumulativeRunnable.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -121,6 +121,7 @@ * @param args the arguments to accumulate */ @SafeVarargs + @SuppressWarnings("varargs") // Copying args is safe public final synchronized void add(T... args) { boolean isSubmitted = true; if (arguments == null) {
--- a/src/share/classes/sun/tools/asm/Assembler.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/tools/asm/Assembler.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -91,9 +91,9 @@ add(new Instruction(where, opc, flagNoCovered)); } - static Vector SourceClassList = new Vector(); + static Vector<String> SourceClassList = new Vector<>(); - static Vector TmpCovTable = new Vector(); + static Vector<String> TmpCovTable = new Vector<>(); static int[] JcovClassCountArray = new int[CT_LAST_KIND + 1]; @@ -177,8 +177,8 @@ case opc_lookupswitch: { SwitchData sw = (SwitchData)inst.value; optimize(env, sw.defaultLabel); - for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) { - optimize(env, (Label)e.nextElement()); + for (Enumeration<Label> e = sw.tab.elements() ; e.hasMoreElements();) { + optimize(env, e.nextElement()); } return; } @@ -186,8 +186,8 @@ case opc_try: { TryData td = (TryData)inst.value; td.getEndLabel().pc = NEEDED; - for (Enumeration e = td.catches.elements() ; e.hasMoreElements();) { - CatchData cd = (CatchData)e.nextElement(); + for (Enumeration<CatchData> e = td.catches.elements() ; e.hasMoreElements();) { + CatchData cd = e.nextElement(); optimize(env, cd.getLabel()); } break; @@ -237,9 +237,11 @@ // Collect constants for arguments only // if a local variable table is generated if ((field != null) && env.debug_vars()) { - if (field.getArguments() != null) { - for (Enumeration e = field.getArguments().elements() ; e.hasMoreElements() ;) { - MemberDefinition f = (MemberDefinition)e.nextElement(); + @SuppressWarnings("unchecked") + Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments(); + if (v != null) { + for (Enumeration<MemberDefinition> e = v.elements() ; e.hasMoreElements() ;) { + MemberDefinition f = e.nextElement(); tab.put(f.getName().toString()); tab.put(f.getType().getTypeSignature()); } @@ -355,16 +357,16 @@ case opc_lookupswitch: { SwitchData sw = (SwitchData)inst.value; balance(sw.defaultLabel, depth); - for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) { - balance((Label)e.nextElement(), depth); + for (Enumeration<Label> e = sw.tab.elements() ; e.hasMoreElements();) { + balance(e.nextElement(), depth); } return; } case opc_try: { TryData td = (TryData)inst.value; - for (Enumeration e = td.catches.elements() ; e.hasMoreElements();) { - CatchData cd = (CatchData)e.nextElement(); + for (Enumeration<CatchData> e = td.catches.elements() ; e.hasMoreElements();) { + CatchData cd = e.nextElement(); balance(cd.getLabel(), depth + 1); } break; @@ -383,9 +385,10 @@ if ((field != null) && field.getArguments() != null) { int sum = 0; - Vector v = field.getArguments(); - for (Enumeration e = v.elements(); e.hasMoreElements(); ) { - MemberDefinition f = ((MemberDefinition)e.nextElement()); + @SuppressWarnings("unchecked") + Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments(); + for (Enumeration<MemberDefinition> e = v.elements(); e.hasMoreElements(); ) { + MemberDefinition f = e.nextElement(); sum += f.getType().stackSize(); } maxvar = sum; @@ -441,8 +444,8 @@ if (inst.opc == opc_try) { TryData td = (TryData)inst.value; writeExceptions(env, out, tab, inst.next, td.getEndLabel()); - for (Enumeration e = td.catches.elements() ; e.hasMoreElements();) { - CatchData cd = (CatchData)e.nextElement(); + for (Enumeration<CatchData> e = td.catches.elements() ; e.hasMoreElements();) { + CatchData cd = e.nextElement(); //System.out.println("EXCEPTION: " + env.getSource() + ", pc=" + inst.pc + ", end=" + td.getEndLabel().pc + ", hdl=" + cd.getLabel().pc + ", tp=" + cd.getType()); out.writeShort(inst.pc); out.writeShort(td.getEndLabel().pc); @@ -463,11 +466,12 @@ * Write the coverage table */ public void writeCoverageTable(Environment env, ClassDefinition c, DataOutputStream out, ConstantPool tab, long whereField) throws IOException { - Vector TableLot = new Vector(); /* Coverage table */ + Vector<Cover> TableLot = new Vector<>(); /* Coverage table */ boolean begseg = false; boolean begmeth = false; + @SuppressWarnings("deprecation") long whereClass = ((SourceClass)c).getWhere(); - Vector whereTry = new Vector(); + Vector<Long> whereTry = new Vector<>(); int numberTry = 0; int count = 0; @@ -484,8 +488,8 @@ } if (!begseg && !inst.flagNoCovered ) { boolean findTry = false; - for (Enumeration e = whereTry.elements(); e.hasMoreElements();) { - if ( ((Long)(e.nextElement())).longValue() == inst.where) { + for (Enumeration<Long> e = whereTry.elements(); e.hasMoreElements();) { + if (e.nextElement().longValue() == inst.where) { findTry = true; break; } @@ -546,7 +550,7 @@ } case opc_try: { - whereTry.addElement(new Long(inst.where)); + whereTry.addElement(Long.valueOf(inst.where)); begseg = false; break; } @@ -569,8 +573,8 @@ } case opc_lookupswitch: { SwitchData sw = (SwitchData)inst.value; - for (Enumeration e = sw.sortedKeys(); e.hasMoreElements() ; ) { - Integer v = (Integer)e.nextElement(); + for (Enumeration<Integer> e = sw.sortedKeys(); e.hasMoreElements() ; ) { + Integer v = e.nextElement(); TableLot.addElement(new Cover(CT_CASE, sw.whereCase(v), inst.pc)); count++; } @@ -591,7 +595,7 @@ out.writeShort(count); for (int i = 0; i < count; i++) { - Lot = (Cover)TableLot.elementAt(i); + Lot = TableLot.elementAt(i); ln = (Lot.Addr >> WHEREOFFSETBITS); pos = (Lot.Addr << (64 - WHEREOFFSETBITS)) >> (64 - WHEREOFFSETBITS); out.writeShort(Lot.NumCommand); @@ -646,6 +650,7 @@ */ public void GenVecJCov(Environment env, ClassDefinition c, long Time) { + @SuppressWarnings("deprecation") String SourceFile = ((SourceClass)c).getAbsoluteName(); TmpCovTable.addElement(createClassJcovElement(env, c)); @@ -667,6 +672,7 @@ * generate file of coverage data */ +@SuppressWarnings("deprecation") // for JCovd.readLine() calls public void GenJCov(Environment env) { try { @@ -686,14 +692,14 @@ while((CurrLine = JCovd.readLine()) != null ) { if ( CurrLine.startsWith(JcovClassLine) ) { first = true; - for(Enumeration e = SourceClassList.elements(); e.hasMoreElements();) { + for(Enumeration<String> e = SourceClassList.elements(); e.hasMoreElements();) { String clsName = CurrLine.substring(JcovClassLine.length()); int idx = clsName.indexOf(' '); if (idx != -1) { clsName = clsName.substring(0, idx); } - Class = (String)e.nextElement(); + Class = e.nextElement(); if ( Class.compareTo(clsName) == 0) { first = false; break; @@ -708,7 +714,7 @@ } PrintStream CovFile = new PrintStream(new DataOutputStream(new FileOutputStream(outFile))); CovFile.println(JcovMagicLine); - for(Enumeration e = TmpCovTable.elements(); e.hasMoreElements();) { + for(Enumeration<String> e = TmpCovTable.elements(); e.hasMoreElements();) { CovFile.println(e.nextElement()); } CovFile.close(); @@ -821,16 +827,16 @@ case opc_lookupswitch: { SwitchData sw = (SwitchData)inst.value; flowFields(env, sw.defaultLabel, locals); - for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) { - flowFields(env, (Label)e.nextElement(), locals); + for (Enumeration<Label> e = sw.tab.elements() ; e.hasMoreElements();) { + flowFields(env, e.nextElement(), locals); } return; } case opc_try: { - Vector catches = ((TryData)inst.value).catches; - for (Enumeration e = catches.elements(); e.hasMoreElements();) { - CatchData cd = (CatchData)e.nextElement(); + Vector<CatchData> catches = ((TryData)inst.value).catches; + for (Enumeration<CatchData> e = catches.elements(); e.hasMoreElements();) { + CatchData cd = e.nextElement(); flowFields(env, cd.getLabel(), locals); } break; @@ -851,9 +857,10 @@ // Initialize arguments if ((field != null) && (field.getArguments() != null)) { int reg = 0; - Vector v = field.getArguments(); - for (Enumeration e = v.elements(); e.hasMoreElements(); ) { - MemberDefinition f = ((MemberDefinition)e.nextElement()); + @SuppressWarnings("unchecked") + Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments(); + for (Enumeration<MemberDefinition> e = v.elements(); e.hasMoreElements(); ) { + MemberDefinition f = e.nextElement(); locals[reg] = f; reg += f.getType().stackSize(); } @@ -867,9 +874,10 @@ locals[i] = null; if ((field != null) && (field.getArguments() != null)) { int reg = 0; - Vector v = field.getArguments(); - for (Enumeration e = v.elements(); e.hasMoreElements(); ) { - MemberDefinition f = ((MemberDefinition)e.nextElement()); + @SuppressWarnings("unchecked") + Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments(); + for (Enumeration<MemberDefinition> e = v.elements(); e.hasMoreElements(); ) { + MemberDefinition f = e.nextElement(); locals[reg] = f; lvtab.define(f, reg, 0, maxpc); reg += f.getType().stackSize();
--- a/src/share/classes/sun/tools/asm/ConstantPool.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/tools/asm/ConstantPool.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,20 +42,20 @@ */ public final class ConstantPool implements RuntimeConstants { - Hashtable hash = new Hashtable(101); + Hashtable<Object,ConstantPoolData> hash = new Hashtable<>(101); /** * Find an entry, may return 0 */ public int index(Object obj) { - return ((ConstantPoolData)hash.get(obj)).index; + return hash.get(obj).index; } /** * Add an entry */ public void put(Object obj) { - ConstantPoolData data = (ConstantPoolData)hash.get(obj); + ConstantPoolData data = hash.get(obj); if (data == null) { if (obj instanceof String) { data = new StringConstantData(this, (String)obj); @@ -87,8 +87,8 @@ // Make a list of all the constant pool items for (int n = 0 ; n < 5 ; n++) { int first = count; - for (Enumeration e = hash.elements() ; e.hasMoreElements() ;) { - ConstantPoolData data = (ConstantPoolData)e.nextElement(); + for (Enumeration<ConstantPoolData> e = hash.elements() ; e.hasMoreElements() ;) { + ConstantPoolData data = e.nextElement(); if (data.order() == n) { keys[count] = sortKey(data); list[count++] = data;
--- a/src/share/classes/sun/tools/asm/Instruction.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/tools/asm/Instruction.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -274,9 +274,9 @@ case opc_lookupswitch: { SwitchData sw = (SwitchData)value; sw.defaultLabel = sw.defaultLabel.getDestination(); - for (Enumeration e = sw.tab.keys() ; e.hasMoreElements() ; ) { - Integer k = (Integer)e.nextElement(); - Label lbl = (Label)sw.tab.get(k); + for (Enumeration<Integer> e = sw.tab.keys() ; e.hasMoreElements() ; ) { + Integer k = e.nextElement(); + Label lbl = sw.tab.get(k); sw.tab.put(k, lbl.getDestination()); } @@ -389,8 +389,8 @@ return; case opc_try: - for (Enumeration e = ((TryData)value).catches.elements() ; e.hasMoreElements() ;) { - CatchData cd = (CatchData)e.nextElement(); + for (Enumeration<CatchData> e = ((TryData)value).catches.elements() ; e.hasMoreElements() ;) { + CatchData cd = e.nextElement(); if (cd.getType() != null) { tab.put(cd.getType()); } @@ -641,6 +641,7 @@ /** * Generate code */ + @SuppressWarnings("fallthrough") void write(DataOutputStream out, ConstantPool tab) throws IOException { switch (opc) { case opc_try: case opc_label: case opc_dead: @@ -770,8 +771,8 @@ } out.writeInt(sw.defaultLabel.pc - pc); out.writeInt(sw.tab.size()); - for (Enumeration e = sw.sortedKeys(); e.hasMoreElements() ; ) { - Integer v = (Integer)e.nextElement(); + for (Enumeration<Integer> e = sw.sortedKeys(); e.hasMoreElements() ; ) { + Integer v = e.nextElement(); out.writeInt(v.intValue()); out.writeInt(sw.get(v).pc - pc); }
--- a/src/share/classes/sun/tools/asm/SwitchData.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/tools/asm/SwitchData.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -39,23 +39,23 @@ class SwitchData { int minValue, maxValue; Label defaultLabel = new Label(); - Hashtable tab = new Hashtable(); + Hashtable<Integer,Label> tab = new Hashtable<>(); // JCOV - Hashtable whereCaseTab = null; + Hashtable<Integer,Long> whereCaseTab = null; // end JCOV /** * Get a label */ public Label get(int n) { - return (Label)tab.get(new Integer(n)); + return tab.get(n); } /** * Get a label */ public Label get(Integer n) { - return (Label)tab.get(n); + return tab.get(n); } /** @@ -73,7 +73,7 @@ maxValue = n; } } - tab.put(new Integer(n), lbl); + tab.put(Integer.valueOf(n), lbl); } /** @@ -86,33 +86,35 @@ /** * Return the keys of this enumaration sorted in ascending order */ - public synchronized Enumeration sortedKeys() { + public synchronized Enumeration<Integer> sortedKeys() { return new SwitchDataEnumeration(tab); } // JCOV public void initTableCase() { - whereCaseTab = new Hashtable(); + whereCaseTab = new Hashtable<Integer,Long>(); } public void addTableCase(int index, long where) { if (whereCaseTab != null) - whereCaseTab.put(new Integer(index), new Long(where)); + whereCaseTab.put(Integer.valueOf(index), Long.valueOf(where)); } + // this puts String key into Hashtable<Integer,Long> + @SuppressWarnings("unchecked") public void addTableDefault(long where) { if (whereCaseTab != null) - whereCaseTab.put("default", new Long(where)); + ((Hashtable)whereCaseTab).put("default", Long.valueOf(where)); } public long whereCase(Object key) { - Long i = (Long) whereCaseTab.get(key); - return (i == null) ? 0 : i.longValue(); + Long i = whereCaseTab.get(key); + return (i == null) ? 0L : i.longValue(); } public boolean getDefault() { - return (whereCase("default") != 0); + return (whereCase("default") != 0L); } // end JCOV } -class SwitchDataEnumeration implements Enumeration { +class SwitchDataEnumeration implements Enumeration<Integer> { private Integer table[]; private int current_index = 0; @@ -121,11 +123,11 @@ * hash table will be an Integer, with the value being a label. The * enumeration returns the keys in sorted order. */ - SwitchDataEnumeration(Hashtable tab) { + SwitchDataEnumeration(Hashtable<Integer,Label> tab) { table = new Integer[tab.size()]; int i = 0; - for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) { - table[i++] = (Integer)e.nextElement(); + for (Enumeration<Integer> e = tab.keys() ; e.hasMoreElements() ; ) { + table[i++] = e.nextElement(); } Arrays.sort(table); current_index = 0; @@ -141,7 +143,7 @@ /** * Return the next key. */ - public Object nextElement() { + public Integer nextElement() { return table[current_index++]; } }
--- a/src/share/classes/sun/tools/asm/TryData.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/tools/asm/TryData.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ */ public final class TryData { - Vector catches = new Vector(); + Vector<CatchData> catches = new Vector<>(); Label endLabel = new Label(); /** @@ -51,7 +51,7 @@ * Get a label */ public CatchData getCatch(int n) { - return (CatchData)catches.elementAt(n); + return catches.elementAt(n); } /**
--- a/src/share/classes/sun/tools/jar/JarException.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/classes/sun/tools/jar/JarException.java Wed Aug 07 19:56:20 2013 -0700 @@ -29,6 +29,9 @@ public class JarException extends IOException { + + static final long serialVersionUID = -4351820108009811497L; + public JarException() { super(); }
--- a/src/share/demo/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/demo/scripting/jconsole-plugin/src/com/sun/demo/scripting/jconsole/ScriptShellPanel.java Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,7 +54,7 @@ * jconsole's script console. */ -class ScriptShellPanel extends JPanel { +public class ScriptShellPanel extends JPanel { private static final long serialVersionUID = 4116273141148726319L;
--- a/src/share/demo/scripting/jconsole-plugin/src/resources/jconsole.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/demo/scripting/jconsole-plugin/src/resources/jconsole.js Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -77,12 +77,37 @@ function jcontext() { return plugin.getContext(); } -jcontext.docString = "returns JConsoleContext for the current jconsole plugin" +jcontext.docString = "returns JConsoleContext for the current jconsole plugin"; function mbeanConnection() { return jcontext().getMBeanServerConnection(); } -mbeanConnection.docString = "returns current MBeanServer connection" +mbeanConnection.docString = "returns current MBeanServer connection"; + +// check if there is a build in sync function, define one if missing +if (typeof sync === "undefined") { + var sync = function(func, obj) { + if (arguments.length < 1 || arguments.length > 2 ) { + throw "sync(function [,object]) parameter count mismatch"; + } + + var syncobj = (arguments.length == 2 ? obj : this); + + if (!syncobj._syncLock) { + syncobj._syncLock = new Lock(); + } + + return function() { + syncobj._syncLock.lock(); + try { + func.apply(null, arguments); + } finally { + syncobj._syncLock.unlock(); + } + }; + }; + sync.docString = "synchronize a function, optionally on an object"; +} /** * Prints one liner help message for each function exposed here @@ -188,22 +213,12 @@ // wraps a script array as java.lang.Object[] function objectArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.Object, len); - for (var i = 0; i < array.length; i++) { - res[i] = array[i]; - } - return res; + return Java.to(array, "java.lang.Object[]"); } // wraps a script (string) array as java.lang.String[] function stringArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.String, len); - for (var i = 0; i < array.length; i++) { - res[i] = String(array[i]); - } - return res; + return Java.to(array, "java.lang.String[]"); } // script array to Java List @@ -286,16 +301,18 @@ * will be of type FutureTask. When you need value, call 'get' on it. */ function mbean(objName, async) { + var index; + objName = objectName(objName); var info = mbeanInfo(objName); var attrs = info.attributes; var attrMap = new Object; - for (var index in attrs) { + for (index in attrs) { attrMap[attrs[index].name] = attrs[index]; } var opers = info.operations; var operMap = new Object; - for (var index in opers) { + for (index in opers) { operMap[opers[index].name] = opers[index]; } @@ -318,21 +335,30 @@ } else { return getMBeanAttribute(objName, name); } - } else if (isOperation(name)) { + } else { + return undefined; + } + }, + __call__: function(name) { + if (isOperation(name)) { var oper = operMap[name]; - return function() { - var params = objectArray(arguments); - var sigs = oper.signature; - var sigNames = new Array(sigs.length); - for (var index in sigs) { - sigNames[index] = sigs[index].getType(); - } - if (async) { - return invokeMBean.future(objName, name, - params, sigNames); - } else { - return invokeMBean(objName, name, params, sigNames); - } + + var params = []; + for (var j = 1; j < arguments.length; j++) { + params[j-1]= arguments[j]; + } + + var sigs = oper.signature; + + var sigNames = new Array(sigs.length); + for (var index in sigs) { + sigNames[index] = sigs[index].getType(); + } + + if (async) { + return invokeMBean.future(objName, name, params, sigNames); + } else { + return invokeMBean(objName, name, params, sigNames); } } else { return undefined; @@ -520,7 +546,7 @@ } finally { lock.unlock(); } -} +}; /** * Causes current thread to sleep for specified @@ -534,8 +560,7 @@ sleep.docString = "wrapper for java.lang.Thread.sleep method"; /** - * Schedules a task to be executed once in - * every N milliseconds specified. + * Schedules a task to be executed once in N milliseconds specified. * * @param callback function or expression to evaluate * @param interval in milliseconds to sleep @@ -549,15 +574,15 @@ // start a new thread that sleeps given time // and calls callback in an infinite loop return (function() { - while (true) { + try { sleep(interval); - callback(); - } + } catch (x) { } + callback(); }).daemon(); } -setTimeout.docString = "calls given callback once after specified interval" +setTimeout.docString = "calls given callback once after specified interval"; -/** +/** * Cancels a timeout set earlier. * @param tid timeout ID returned from setTimeout */ @@ -565,6 +590,45 @@ // we just interrupt the timer thread tid.interrupt(); } +clearTimeout.docString = "interrupt a setTimeout timer"; + +/** + * Schedules a task to be executed once in + * every N milliseconds specified. + * + * @param callback function or expression to evaluate + * @param interval in milliseconds to sleep + * @return timeout ID (which is nothing but Thread instance) + */ +function setInterval(callback, interval) { + if (! (callback instanceof Function)) { + callback = new Function(callback); + } + + // start a new thread that sleeps given time + // and calls callback in an infinite loop + return (function() { + while (true) { + try { + sleep(interval); + } catch (x) { + break; + } + callback(); + } + }).daemon(); +} +setInterval.docString = "calls given callback every specified interval"; + +/** + * Cancels a timeout set earlier. + * @param tid timeout ID returned from setTimeout + */ +function clearInterval(tid) { + // we just interrupt the timer thread + tid.interrupt(); +} +clearInterval.docString = "interrupt a setInterval timer"; /** * Simple access to thread local storage. @@ -680,7 +744,7 @@ if (msg === undefined) msg = "undefined"; if (msg === null) msg = "null"; if (title == undefined) title = msg; - if (msgType == undefined) type = JOptionPane.INFORMATION_MESSAGE; + if (msgType == undefined) msgType = JOptionPane.INFORMATION_MESSAGE; JOptionPane.showMessageDialog(window, msg, title, msgType); } if (isEventThread()) { @@ -800,7 +864,7 @@ * Clear the screen */ function clear() { - (function() { window.clear(false) }).invokeLater(); + (function() { window.clear(false); }).invokeLater(); } clear.docString = "clears interactive console screen";
--- a/src/share/demo/scripting/jconsole-plugin/src/scripts/invoke.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/demo/scripting/jconsole-plugin/src/scripts/invoke.js Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,6 +53,6 @@ * */ function resetPeakThreadCount() { - return invokeMBean("java.lang:type=Threading", "resetPeakThreadCount", [], ""); + return invokeMBean("java.lang:type=Threading", "resetPeakThreadCount", [], {}); }
--- a/src/share/demo/scripting/jconsole-plugin/src/scripts/jstack.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/demo/scripting/jconsole-plugin/src/scripts/jstack.js Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,16 +43,16 @@ * threads.'jstack' function which can be called once or periodically * from a timer thread (calling it periodically would slow down the target * application). To call this once, just call 'jstack()' in script - * console prompt. To call jtop in a timer thread, you can use + * console prompt. To call jstack in a timer thread, you can use * - * var t = setTimeout(function () { jstack(print); }, 5000); + * var t = setInterval(function () { jstack(print); }, 5000); * * The above call prints threads in sorted order for every 5 seconds. * The print output goes to OS console window from which jconsole was * started. The timer can be cancelled later by clearTimeout() function * as shown below: * - * clearTimeout(t); + * clearInterval(t); */ @@ -87,7 +87,7 @@ var tmbean = newPlatformMXBeanProxy( "java.lang:type=Threading", - java.lang.management.ThreadMXBean); + java.lang.management.ThreadMXBean.class); var tids = tmbean.allThreadIds; var tinfos = tmbean["getThreadInfo(long[],int)"](tids, maxFrames);
--- a/src/share/demo/scripting/jconsole-plugin/src/scripts/jtop.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/demo/scripting/jconsole-plugin/src/scripts/jtop.js Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,14 +45,14 @@ * To call this once, just call 'jtop()' in script console prompt. * To call jtop in a timer thread, you can use * - * var t = setTimeout(function () { jtop(print); }, 2000); + * var t = setInterval(function () { jtop(print); }, 2000); * * The above call prints threads in sorted order for every 2 seconds. * The print output goes to OS console window from which jconsole was * started. The timer can be cancelled later by clearTimeout() function * as shown below: - * - * clearTimeout(t); + * + * clearInterval(t); */ /** @@ -62,10 +62,10 @@ function getThreadList() { var tmbean = newPlatformMXBeanProxy( "java.lang:type=Threading", - java.lang.management.ThreadMXBean); + java.lang.management.ThreadMXBean.class); if (!tmbean.isThreadCpuTimeSupported()) { - return; + return java.util.Collections.EMPTY_LIST; } tmbean.setThreadCpuTimeEnabled(true);
--- a/src/share/demo/scripting/jconsole-plugin/src/scripts/sysprops.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/demo/scripting/jconsole-plugin/src/scripts/sysprops.js Wed Aug 07 19:56:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,16 +43,16 @@ * properties.'sysprops' function which can be called once or periodically * from a timer thread (calling it periodically would slow down the target * application). To call this once, just call 'sysprops()' in script - * console prompt. To call jtop in a timer thread, you can use + * console prompt. To call sysprops in a timer thread, you can use * - * var t = setTimeout(function () { sysprops(print); }, 5000); + * var t = setInterval(function () { sysprops(print); }, 5000); * * The above call prints threads in sorted order for every 5 seconds. * The print output goes to OS console window from which jconsole was * started. The timer can be cancelled later by clearTimeout() function * as shown below: * - * clearTimeout(t); + * clearInterval(t); */ @@ -62,7 +62,7 @@ function getSystemProps() { var runtimeBean = newPlatformMXBeanProxy( "java.lang:type=Runtime", - java.lang.management.RuntimeMXBean); + java.lang.management.RuntimeMXBean.class); return runtimeBean.systemProperties; }
--- a/src/share/sample/scripting/scriptpad/README.txt Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/sample/scripting/scriptpad/README.txt Wed Aug 07 19:56:20 2013 -0700 @@ -108,7 +108,7 @@ java -Dcom.sun.management.jmxremote.port=1090 \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false \ - -jar $JDK_HOME/demo/jfc/Java2D/Java2Demo.jar + -jar $JDK_HOME/demo/jfc/Font2DTest/Font2DTest.jar (2) Start scriptpad and click on "Tools->JMX Connect" menu. In the prompt, enter "localhost:1090" to connect to the above
--- a/src/share/sample/scripting/scriptpad/src/resources/conc.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/sample/scripting/scriptpad/src/resources/conc.js Wed Aug 07 19:56:20 2013 -0700 @@ -221,7 +221,7 @@ * @return timeout ID (which is nothing but Thread instance) */ function setTimeout(callback, interval) { - if (! (callback instanceof Function) && typeof callback !== "function") { + if (! (callback instanceof Function)) { callback = new Function(callback); } @@ -255,7 +255,7 @@ * @return timeout ID (which is nothing but Thread instance) */ function setInterval(callback, interval) { - if (! (callback instanceof Function) && typeof callback !== "function") { + if (! (callback instanceof Function)) { callback = new Function(callback); }
--- a/src/share/sample/scripting/scriptpad/src/resources/mm.js Wed Aug 07 19:52:47 2013 -0700 +++ b/src/share/sample/scripting/scriptpad/src/resources/mm.js Wed Aug 07 19:56:20 2013 -0700 @@ -159,22 +159,12 @@ // wraps a script array as java.lang.Object[] function objectArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.Object, len); - for (var i = 0; i < array.length; i++) { - res[i] = array[i]; - } - return res; + return Java.to(array, "java.lang.Object[]"); } // wraps a script (string) array as java.lang.String[] function stringArray(array) { - var len = array.length; - var res = java.lang.reflect.Array.newInstance(java.lang.String, len); - for (var i = 0; i < array.length; i++) { - res[i] = String(array[i]); - } - return res; + return Java.to(array, "java.lang.String[]"); } // script array to Java List @@ -284,26 +274,35 @@ __get__: function (name) { if (isAttribute(name)) { if (async) { - return getMBeanAttribute.future(objName, name); + return getMBeanAttribute.future(objName, name); } else { - return getMBeanAttribute(objName, name); + return getMBeanAttribute(objName, name); } - } else if (isOperation(name)) { + } else { + return undefined; + } + }, + __call__: function(name) { + if (isOperation(name)) { var oper = operMap[name]; - return function() { - var params = objectArray(arguments); - var sigs = oper.signature; - var sigNames = new Array(sigs.length); - for (var index in sigs) { - sigNames[index] = sigs[index].getType(); - } - if (async) { - return invokeMBean.future(objName, name, - params, sigNames); - } else { - return invokeMBean(objName, name, params, sigNames); - } - }; + + var params = []; + for (var j = 1; j < arguments.length; j++) { + params[j-1]= arguments[j]; + } + + var sigs = oper.signature; + + var sigNames = new Array(sigs.length); + for (var index in sigs) { + sigNames[index] = sigs[index].getType(); + } + + if (async) { + return invokeMBean.future(objName, name, params, sigNames); + } else { + return invokeMBean(objName, name, params, sigNames); + } } else { return undefined; }
--- a/src/solaris/native/java/lang/java_props_md.c Wed Aug 07 19:52:47 2013 -0700 +++ b/src/solaris/native/java/lang/java_props_md.c Wed Aug 07 19:56:20 2013 -0700 @@ -361,6 +361,25 @@ *std_encoding = "Big5-HKSCS-2001"; } #endif +#ifdef MACOSX + /* + * For the case on MacOS X where encoding is set to US-ASCII, but we + * don't have any encoding hints from LANG/LC_ALL/LC_CTYPE, use UTF-8 + * instead. + * + * The contents of ASCII files will still be read and displayed + * correctly, but so will files containing UTF-8 characters beyond the + * standard ASCII range. + * + * Specifically, this allows apps launched by double-clicking a .jar + * file to correctly read UTF-8 files using the default encoding (see + * 8011194). + */ + if (strcmp(p,"US-ASCII") == 0 && getenv("LANG") == NULL && + getenv("LC_ALL") == NULL && getenv("LC_CTYPE") == NULL) { + *std_encoding = "UTF-8"; + } +#endif } free(temp);
--- a/src/windows/native/java/lang/java_props_md.c Wed Aug 07 19:52:47 2013 -0700 +++ b/src/windows/native/java/lang/java_props_md.c Wed Aug 07 19:56:20 2013 -0700 @@ -443,6 +443,7 @@ case 0: sprops.os_name = "Windows Vista"; break; case 1: sprops.os_name = "Windows 7"; break; case 2: sprops.os_name = "Windows 8"; break; + case 3: sprops.os_name = "Windows 8.1"; break; default: sprops.os_name = "Windows NT (unknown)"; } } else { @@ -450,6 +451,7 @@ case 0: sprops.os_name = "Windows Server 2008"; break; case 1: sprops.os_name = "Windows Server 2008 R2"; break; case 2: sprops.os_name = "Windows Server 2012"; break; + case 3: sprops.os_name = "Windows Server 2012 R2"; break; default: sprops.os_name = "Windows NT (unknown)"; } }
--- a/src/windows/resource/java.manifest Wed Aug 07 19:52:47 2013 -0700 +++ b/src/windows/resource/java.manifest Wed Aug 07 19:56:20 2013 -0700 @@ -44,8 +44,14 @@ <!-- Indicate this JDK version is Windows 7 compatible --> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> + <!-- Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!-- Windows 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!-- Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <!-- Windows 8.1 --> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> </application> </compatibility>
--- a/test/ProblemList.txt Wed Aug 07 19:52:47 2013 -0700 +++ b/test/ProblemList.txt Wed Aug 07 19:56:20 2013 -0700 @@ -138,6 +138,9 @@ java/lang/instrument/RedefineBigClass.sh linux-x64 java/lang/instrument/RetransformBigClass.sh linux-x64 +# 8021230 +java/lang/ThreadLocal/ThreadLocalSupplierTest.java generic-all + ############################################################################ @@ -367,9 +370,6 @@ # Filed 6772009 java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all -# 8020435 -java/util/concurrent/CompletableFuture/Basic.java generic-all - # 7041639, Solaris DSA keypair generation bug java/util/TimeZone/TimeZoneDatePermissionCheck.sh solaris-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacEncoding/ExpectedEncoding.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,66 @@ +/* + * 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. + */ + +/** + * Check that the value of file.encoding and sun.jnu.encoding match the expected + * values passed in on the command-line. + */ +public class ExpectedEncoding { + public static void main(String[] args) { + boolean failed = false; + if (args.length != 2) { + System.out.println("Usage:"); + System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>"); + System.out.println("$ use \"skip\" to skip checking property's value"); + System.exit(1); + } + String expectFileEnc = args[0]; + String expectSunJnuEnc = args[1]; + + String fileEnc = System.getProperty("file.encoding"); + String jnuEnc = System.getProperty("sun.jnu.encoding"); + + if ("skip".equals(expectFileEnc)) { + System.err.println("Expected file.encoding is \"skip\", ignoring"); + } else { + System.err.println("Expected file.encoding: " + expectFileEnc); + System.err.println("Actual file.encoding: " + fileEnc); + if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { + failed = true; + } + } + if ("skip".equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding is \"skip\", ignoring"); + } else { + if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); + System.err.println("Actual sun.jnu.encoding: " + jnuEnc); + failed = true; + } + } + + if (failed) { + throw new RuntimeException("Test Failed"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacEncoding/MacJNUEncoding.sh Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,101 @@ +#!/bin/sh + +# +# 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 8003228 +# @summary Test the value of sun.jnu.encoding on Mac +# @author Brent Christian +# +# @run shell MacJNUEncoding.sh + +# Only run test on Mac +OS=`uname -s` +case "$OS" in + Darwin ) ;; + * ) + exit 0 + ;; +esac + +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${COMPILEJAVA}" = "" ]; then + COMPILEJAVA="${TESTJAVA}" +fi + + +if [ "${TESTSRC}" = "" ] +then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASSES not set. Test cannot execute. Failed." + exit 1 +fi + +JAVAC="${COMPILEJAVA}"/bin/javac +JAVA="${TESTJAVA}"/bin/java + +echo "Building test classes..." +"$JAVAC" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java + +echo "" +echo "Running test for C locale" +export LANG=C +export LC_ALL=C +"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8 +result1=$? + +echo "" +echo "Running test for en_US.UTF-8 locale" +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 +"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8 +result2=$? + +echo "" +echo "Cleanup" +rm ${TESTCLASSES}/ExpectedEncoding.class + +if [ ${result1} -ne 0 ] ; then + echo "Test failed for C locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" + exit ${result1} +fi +if [ ${result2} -ne 0 ] ; then + echo "Test failed for en_US.UTF-8 locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" + exit ${result2} +fi +exit 0 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacEncoding/TestFileEncoding.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; + +/* + * @test + * @bug 8011194 + * @summary Test value of file.encoding for corresponding value of LANG, etc + * @library ../../../../tools/launcher/ ../ + * @build TestHelper TestFileEncoding ExpectedEncoding + * @run main TestFileEncoding UTF-8 + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding + * @run main TestFileEncoding UTF-8 en_US.UTF-8 + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding en_US.UTF-8 + * @run main TestFileEncoding US-ASCII C + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding C + * @author Brent Christian + */ + +/** + * Setup the environment and run a sub-test to check the expected value of + * file.encoding, based on the value(s) of encoding-related environment vars + * (LANG, LC_ALL, LC_CTYPE). + * + * The first argument (required) is the expected value of the + * file.encoding System property. + * The second argument (optional) is the value to set to the LANG/etc env vars. + */ +public class TestFileEncoding { + private static final String TEST_NAME = "ExpectedEncoding"; + + private String expectedEncoding; // Expected value for file.encoding + private String langVar = null; // Value to set for LANG, etc + + private static Set<String> envToRm = new HashSet<>(3); + static { + // Take these vars out of the test's run environment, possibly adding + // our own value back in. + envToRm.add("LANG"); + envToRm.add("LC_ALL"); + envToRm.add("LC_CTYPE"); + } + + public TestFileEncoding(String expectedEncoding) { + this.expectedEncoding = expectedEncoding; + } + + public TestFileEncoding(String expectedEncoding, String langVar) { + this.expectedEncoding = expectedEncoding; + this.langVar = langVar; + } + + /* + * Launch ExpectedEncoding with the given parameters, check for the + * expected file.encoding. + */ + private void run() { + String testClasses = System.getProperty("test.classes"); + + // Pick up VM opts + String vmOptsStr = System.getProperty("test.vm.opts"); + System.out.println("test.vm.opts: " + vmOptsStr); + String[] vmOpts = new String[0]; + if (vmOptsStr != null && !"".equals(vmOptsStr)) { + vmOpts = vmOptsStr.split(" "); + System.out.println("found vm options:"); + for (String opt : vmOpts) { + System.out.println(" <" + opt + ">"); + } + } + + // Build java cmd + LinkedList<String> cmdList = new LinkedList<>(); + cmdList.add(TestHelper.javaCmd); + for (String vmOpt : vmOpts) { + if (vmOpt != null && !vmOpt.equals("")) { + cmdList.add(vmOpt); + } + } + + // See if the user specified a file.encoding that we should pass through + String userEncoding = System.getProperty("userEncoding"); + if (userEncoding != null) { + cmdList.add("-Dfile.encoding="+userEncoding); + } + + cmdList.add("-cp"); + cmdList.add(testClasses); + cmdList.add(TEST_NAME); + cmdList.add(expectedEncoding); + cmdList.add("skip"); // ignore sun.jnu.encoding for this test + + String cmdArray[] = new String[cmdList.size()]; + cmdList.toArray(cmdArray); + + // Run the test(s) + if (langVar == null) { + System.out.println("TestFileEncoding: Running with no envvars set"); + TestHelper.TestResult tr = TestHelper.doExec(null, envToRm, + cmdArray); + checkResult(tr); + } else { + runWithEnvVar("LANG", cmdArray); + runWithEnvVar("LC_ALL", cmdArray); + runWithEnvVar("LC_CTYPE", cmdArray); + } + } + + /* + * Run the test, setting the environment named by envVarName to the value + * in langVar. + */ + private void runWithEnvVar(String envVarName, String[] cmdArray) { + Map<String, String> envToAdd = new HashMap<>(1); + TestHelper.TestResult tr = null; + + System.out.println("TestFileEncoding: Running with " + envVarName + "=" + langVar); + envToAdd.put(envVarName, langVar); + tr = TestHelper.doExec(envToAdd, envToRm, cmdArray); + checkResult(tr); + } + + private void checkResult(TestHelper.TestResult tr) { + System.out.println(tr); + if (!tr.isOK()) { + throw new RuntimeException("TEST FAILED: !tr.isOK()"); + } + } + + public static void main(String[] args) { + TestFileEncoding cfe = null; + if (!TestHelper.isMacOSX) { + System.out.println("Test is currently only for Mac OS X - pass."); + return; + } + if (args.length == 1) { + cfe = new TestFileEncoding(args[0]); + } else if (args.length == 2) { + cfe = new TestFileEncoding(args[0], args[1]); + } else { + System.out.println("Usage: TestFileEncoding <expected file.encoding>"); + System.out.println(" TestFileEncoding <expected file.encoding> <value for LANG/etc env var>"); + return; + } + cfe.run(); + } +}
--- a/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java Wed Aug 07 19:52:47 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * 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. - */ - -/** - * Check that the value of file.encoding and sun.jnu.encoding match the expected - * values passed in on the command-line. - */ -public class ExpectedEncoding { - public static void main(String[] args) { - boolean failed = false; - if (args.length != 2) { - System.out.println("Usage:"); - System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>"); - System.exit(1); - } - String expectFileEnc = args[0]; - String expectSunJnuEnc = args[1]; - - String fileEnc = System.getProperty("file.encoding"); - String jnuEnc = System.getProperty("sun.jnu.encoding"); - - if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { - System.err.println("Expected file.encoding: " + expectFileEnc); - System.err.println("Actual file.encoding: " + fileEnc); - failed = true; - } - if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { - System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); - System.err.println("Actual sun.jnu.encoding: " + jnuEnc); - failed = true; - } - if (failed) { - throw new RuntimeException("Test Failed"); - } - } -}
--- a/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh Wed Aug 07 19:52:47 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -#!/bin/sh - -# -# 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 8003228 -# @summary Test the value of sun.jnu.encoding on Mac -# @author Brent Christian -# -# @run shell MacJNUEncoding.sh - -# Only run test on Mac -OS=`uname -s` -case "$OS" in - Darwin ) ;; - * ) - exit 0 - ;; -esac - -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${COMPILEJAVA}" = "" ]; then - COMPILEJAVA="${TESTJAVA}" -fi - - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVAC="${COMPILEJAVA}"/bin/javac -JAVA="${TESTJAVA}"/bin/java - -echo "Building test classes..." -"$JAVAC" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java - -echo "" -echo "Running test for C locale" -export LANG=C -export LC_ALL=C -"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8 -result1=$? - -echo "" -echo "Running test for en_US.UTF-8 locale" -export LANG=en_US.UTF-8 -export LC_ALL=en_US.UTF-8 -"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8 -result2=$? - -echo "" -echo "Cleanup" -rm ${TESTCLASSES}/ExpectedEncoding.class - -if [ ${result1} -ne 0 ] ; then - echo "Test failed for C locale" - echo " LANG=\"${LANG}\"" - echo " LC_ALL=\"${LC_ALL}\"" - exit ${result1} -fi -if [ ${result2} -ne 0 ] ; then - echo "Test failed for en_US.UTF-8 locale" - echo " LANG=\"${LANG}\"" - echo " LC_ALL=\"${LC_ALL}\"" - exit ${result2} -fi -exit 0 -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2013, 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 + * @summary Test locating and invoking default/static method that defined + * in interfaces and/or in inheritance + * @bug 7184826 + * @build helper.Mod helper.Declared DefaultStaticTestData + * @run testng DefaultStaticInvokeTest + * @author Yong Lu + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +import static helper.Mod.*; +import static helper.Declared.*; +import helper.Mod; + +public class DefaultStaticInvokeTest { + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testGetMethods(String testTarget, Object param) + throws Exception { + // test the methods retrieved by getMethods() + testMethods(ALL_METHODS, testTarget, param); + } + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testGetDeclaredMethods(String testTarget, Object param) + throws Exception { + // test the methods retrieved by getDeclaredMethods() + testMethods(DECLARED_ONLY, testTarget, param); + } + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testMethodInvoke(String testTarget, Object param) + throws Exception { + Class<?> typeUnderTest = Class.forName(testTarget); + MethodDesc[] expectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + + // test the method retrieved by Class.getMethod(String, Object[]) + for (MethodDesc toTest : expectedMethods) { + String name = toTest.name(); + Method m = getTestMethod(typeUnderTest, name, param); + testThisMethod(toTest, m, typeUnderTest, param); + } + } + + @Test(dataProvider = "testCasesAll", + dataProviderClass = DefaultStaticTestData.class) + public void testMethodHandleInvoke(String testTarget, Object param) + throws Throwable { + Class<?> typeUnderTest = Class.forName(testTarget); + MethodDesc[] expectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + + for (MethodDesc toTest : expectedMethods) { + String mName = toTest.name(); + Mod mod = toTest.mod(); + if (mod != STATIC && typeUnderTest.isInterface()) { + return; + } + + String result = null; + String expectedReturn = toTest.retval(); + + MethodHandle methodHandle = getTestMH(typeUnderTest, mName, param); + if (mName.equals("staticMethod")) { + result = (param == null) + ? (String) methodHandle.invoke() + : (String) methodHandle.invoke(param); + } else { + result = (param == null) + ? (String) methodHandle.invoke(typeUnderTest.newInstance()) + : (String) methodHandle.invoke(typeUnderTest.newInstance(), param); + } + + assertEquals(result, expectedReturn); + } + + } + + @Test(dataProvider = "testClasses", + dataProviderClass = DefaultStaticTestData.class) + public void testIAE(String testTarget, Object param) + throws ClassNotFoundException { + + Class<?> typeUnderTest = Class.forName(testTarget); + MethodDesc[] expectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + + for (MethodDesc toTest : expectedMethods) { + String mName = toTest.name(); + Mod mod = toTest.mod(); + if (mod != STATIC && typeUnderTest.isInterface()) { + return; + } + Exception caught = null; + try { + getTestMH(typeUnderTest, mName, param, true); + } catch (Exception e) { + caught = e; + } + assertTrue(caught != null); + assertEquals(caught.getClass(), IllegalAccessException.class); + } + } + private static final String[] OBJECT_METHOD_NAMES = { + "equals", + "hashCode", + "getClass", + "notify", + "notifyAll", + "toString", + "wait", + "wait", + "wait",}; + private static final String LAMBDA_METHOD_NAMES = "lambda$"; + private static final HashSet<String> OBJECT_NAMES = new HashSet<>(Arrays.asList(OBJECT_METHOD_NAMES)); + private static final boolean DECLARED_ONLY = true; + private static final boolean ALL_METHODS = false; + + private void testMethods(boolean declaredOnly, String testTarget, Object param) + throws Exception { + Class<?> typeUnderTest = Class.forName(testTarget); + Method[] methods = declaredOnly + ? typeUnderTest.getDeclaredMethods() + : typeUnderTest.getMethods(); + + MethodDesc[] baseExpectedMethods = typeUnderTest.getAnnotationsByType(MethodDesc.class); + MethodDesc[] expectedMethods; + + // If only declared filter out non-declared from expected result + if (declaredOnly) { + int nonDeclared = 0; + for (MethodDesc desc : baseExpectedMethods) { + if (desc.declared() == NO) { + nonDeclared++; + } + } + expectedMethods = new MethodDesc[baseExpectedMethods.length - nonDeclared]; + int i = 0; + for (MethodDesc desc : baseExpectedMethods) { + if (desc.declared() == YES) { + expectedMethods[i++] = desc; + } + } + } else { + expectedMethods = baseExpectedMethods; + } + + HashMap<String, Method> myMethods = new HashMap<>(methods.length); + for (Method m : methods) { + String mName = m.getName(); + // don't add Object methods and method created from lambda expression + if ((!OBJECT_NAMES.contains(mName)) && (!mName.contains(LAMBDA_METHOD_NAMES))) { + myMethods.put(mName, m); + } + } + assertEquals(expectedMethods.length, myMethods.size()); + + for (MethodDesc toTest : expectedMethods) { + + String name = toTest.name(); + Method candidate = myMethods.get(name); + + assertNotNull(candidate); + myMethods.remove(name); + + testThisMethod(toTest, candidate, typeUnderTest, param); + + } + + // Should be no methods left since we remove all we expect to see + assertTrue(myMethods.isEmpty()); + } + + private void testThisMethod(MethodDesc toTest, Method method, + Class<?> typeUnderTest, Object param) throws Exception { + // Test modifiers, and invoke + Mod mod = toTest.mod(); + String expectedReturn = toTest.retval(); + switch (mod) { + case STATIC: + //assert candidate is static + assertTrue(Modifier.isStatic(method.getModifiers())); + assertFalse(method.isDefault()); + + // Test invoke it + assertEquals(tryInvoke(method, null, param), expectedReturn); + break; + case DEFAULT: + // if typeUnderTest is a class then instantiate and invoke + if (!typeUnderTest.isInterface()) { + assertEquals(tryInvoke( + method, + typeUnderTest, + param), + expectedReturn); + } + + //assert candidate is default + assertFalse(Modifier.isStatic(method.getModifiers())); + assertTrue(method.isDefault()); + break; + case REGULAR: + // if typeUnderTest must be a class + assertEquals(tryInvoke( + method, + typeUnderTest, + param), + expectedReturn); + + //assert candidate is neither default nor static + assertFalse(Modifier.isStatic(method.getModifiers())); + assertFalse(method.isDefault()); + break; + case ABSTRACT: + //assert candidate is neither default nor static + assertFalse(Modifier.isStatic(method.getModifiers())); + assertFalse(method.isDefault()); + break; + default: + assertFalse(true); //this should never happen + break; + } + + } + + private Object tryInvoke(Method m, Class<?> receiverType, Object param) + throws Exception { + Object receiver = receiverType == null ? null : receiverType.newInstance(); + Object result = null; + if (param == null) { + result = m.invoke(receiver); + } else { + result = m.invoke(receiver, param); + } + return result; + } + + private Method getTestMethod(Class clazz, String methodName, Object param) + throws NoSuchMethodException { + Class[] paramsType = (param != null) + ? new Class[]{Object.class} + : new Class[]{}; + return clazz.getMethod(methodName, paramsType); + } + + private MethodHandle getTestMH(Class clazz, String methodName, Object param) + throws Exception { + return getTestMH(clazz, methodName, param, false); + } + + private MethodHandle getTestMH(Class clazz, String methodName, + Object param, boolean isNegativeTest) + throws Exception { + MethodType mType = (param != null) + ? MethodType.genericMethodType(1) + : MethodType.methodType(String.class); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + if (!isNegativeTest) { + return methodName.equals("staticMethod") + ? lookup.findStatic(clazz, methodName, mType) + : lookup.findVirtual(clazz, methodName, mType); + } else { + return methodName.equals("staticMethod") + ? lookup.findVirtual(clazz, methodName, mType) + : lookup.findStatic(clazz, methodName, mType); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2013, 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 Data used for testing default/static method + * + * @author Yong Lu + */ + +import java.util.Arrays; +import java.util.List; + +import org.testng.annotations.DataProvider; +import org.testng.collections.Lists; + +import static helper.Mod.*; +import static helper.Declared.*; +import helper.Mod; +import helper.Declared; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF1 { + + default String defaultMethod() { + return "TestIF1.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass1 implements TestIF1 { +} + +@MethodDesc(name = "staticMethod", retval = "TestIF2.staticMethod", mod = STATIC, declared = YES) +interface TestIF2 { + + static String staticMethod() { + return "TestIF2.staticMethod"; + } +} + +@MethodDesc(name = "method", retval = "TestIF2.staticMethod", mod = REGULAR, declared = YES) +class TestClass2 implements TestIF2 { + + public String method() { + return TestIF2.staticMethod(); + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF3.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF3 { + + String method(); + + default String defaultMethod() { + return "TestIF3.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF3.defaultMethod", mod = DEFAULT, declared = NO) +@MethodDesc(name = "method", retval = "TestClass3.method", mod = REGULAR, declared = YES) +class TestClass3 implements TestIF3 { + + public String method() { + return "TestClass3.method"; + } +} + +@MethodDesc(name = "staticMethod", retval = "TestIF4.staticMethod", mod = STATIC, declared = YES) +@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF4 { + + String method(); + + static String staticMethod() { + return "TestIF4.staticMethod"; + } +} + +@MethodDesc(name = "method", retval = "TestClass4.method", mod = REGULAR, declared = YES) +class TestClass4 implements TestIF4 { + + public String method() { + return "TestClass4.method"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF5.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF5.staticMethod", mod = STATIC, declared = YES) +interface TestIF5 { + + default String defaultMethod() { + return "TestIF5.defaultMethod"; + } + + static String staticMethod() { + return "TestIF5.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF5.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass5 implements TestIF5 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF6.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF6.staticMethod", mod = STATIC, declared = YES) +@MethodDesc(name = "method", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF6 { + + String method(); + + default String defaultMethod() { + return "TestIF6.defaultMethod"; + } + + static String staticMethod() { + return "TestIF6.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF6.defaultMethod", mod = DEFAULT, declared = NO) +@MethodDesc(name = "method", retval = "TestClass6.method", mod = REGULAR, declared = YES) +class TestClass6 implements TestIF6 { + + public String method() { + return "TestClass6.method"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF7.TestClass7", mod = DEFAULT, declared = YES) +interface TestIF7<T> { + + default T defaultMethod(T t) { + return t; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF7.TestClass7", mod = DEFAULT, declared = NO) +class TestClass7<T> implements TestIF7<T> { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF8.TestClass8", mod = DEFAULT, declared = YES) +interface TestIF8<E> { + + default <E> E defaultMethod(E e) { + return e; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF8.TestClass8", mod = DEFAULT, declared = NO) +class TestClass8<T> implements TestIF8<T> { +}; + +@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF9 extends TestIF1 { + + default String defaultMethod() { + return "TestIF9.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass9 implements TestIF9 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF9.defaultMethod", mod = DEFAULT, declared = NO) +@MethodDesc(name = "method", retval = "TestIF9.defaultMethod", mod = REGULAR, declared = YES) +class TestClass91 implements TestIF9, TestIF1 { + + public String method() { + return defaultMethod(); + } +} + +@MethodDesc(name = "staticMethod", retval = "TestIF10.staticMethod", mod = STATIC, declared = YES) +interface TestIF10 extends TestIF2 { + + static String staticMethod() { + + return "TestIF10.staticMethod"; + } +} + +@MethodDesc(name = "staticMethod", retval = "TestIF11.staticMethod", mod = STATIC, declared = YES) +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +interface TestIF11 extends TestIF1 { + + static String staticMethod() { + return "TestIF11.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass11 implements TestIF11 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF2.staticMethod", mod = STATIC, declared = NO) +interface TestIF12 extends TestIF2 { + + default String defaultMethod() { + return "TestIF12.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF12.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass12 implements TestIF12 { +} + +//Diamond Case +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +interface TestIF1A extends TestIF1 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +interface TestIF1B extends TestIF1 { +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass13 implements TestIF1A, TestIF1B { +} + +//Diamond Override Case +@MethodDesc(name = "defaultMethod", retval = "TestIF1C.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF1C extends TestIF1 { + + default String defaultMethod() { + return "TestIF1C.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF1D.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF1D extends TestIF1 { + + default String defaultMethod() { + return "TestIF1D.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestClass14.defaultMethod", mod = REGULAR, declared = YES) +class TestClass14 implements TestIF1C, TestIF1D { + + public String defaultMethod() { + return "TestClass14.defaultMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "", mod = ABSTRACT, declared = YES) +interface TestIF15 extends TestIF1 { + + String defaultMethod(); +} + +@MethodDesc(name = "defaultMethod", retval = "TestClass15.defaultMethod", mod = REGULAR, declared = YES) +class TestClass15 implements TestIF15 { + + public String defaultMethod() { + return "TestClass15.defaultMethod"; + } +} + +interface FuncInterface<T> { + + String test(T t); +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF16.defaultMethod", mod = DEFAULT, declared = YES) +interface TestIF16 { + + default String defaultMethod() { + FuncInterface<Object> fi = o -> o.toString(); + Object o = "TestIF16.defaultMethod"; + return fi.test(o); + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF16.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass16 implements TestIF16 { +}; + +@MethodDesc(name = "defaultMethod", retval = "TestIF17.defaultMethod", mod = DEFAULT, declared = YES) +@MethodDesc(name = "staticMethod", retval = "TestIF17.staticMethod", mod = STATIC, declared = YES) +interface TestIF17 { + + default String defaultMethod() { + return staticMethod().replace("staticMethod", "defaultMethod"); + } + + public static String staticMethod() { + return "TestIF17.staticMethod"; + } +} + +@MethodDesc(name = "defaultMethod", retval = "TestIF17.defaultMethod", mod = DEFAULT, declared = NO) +class TestClass17 implements TestIF17 { +} + +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(MethodDescs.class) +@interface MethodDesc { + String name(); + String retval(); + Mod mod(); + Declared declared(); +} + +@Retention(RetentionPolicy.RUNTIME) +@interface MethodDescs { + MethodDesc[] value(); +} + +public class DefaultStaticTestData { + + /** + * Test data for DefaultStaticInvokeTest The format of inner array is: First + * data is the name of the class under test Second data used in test as the + * arguments used for the method call. + */ + @DataProvider + static Object[][] testClasses() { + return new Object[][]{ + {"TestClass1", null}, + //{"TestClass2", null}, @ignore due to JDK-8009411 + {"TestClass3", null}, + //{"TestClass4", null}, @ignore due to JDK-8009411 + //{"TestClass5", null}, @ignore due to JDK-8009411 + //{"TestClass6", null}, @ignore due to JDK-8009411 + {"TestClass7", "TestIF7.TestClass7"}, + {"TestClass8", "TestIF8.TestClass8"}, + {"TestClass9", null}, + {"TestClass91", null}, + //{"TestClass11", null}, @ignore due to JDK-8009411 + //{"TestClass12", null}, @ignore due to JDK-8009411 + {"TestClass13", null}, + {"TestClass14", null}, + {"TestClass15", null}, + {"TestClass16", null} + //{"TestClass17", null} @ignore due to JDK-8009411 + }; + } + + /** + * Test data for DefaultStaticInvokeTest The format of inner array is: First + * data is the name of the interface under test Second data used in test as + * the arguments used for the method call. + */ + @DataProvider + static Object[][] testInterfaces() { + return new Object[][]{ + {"TestIF1", null}, + {"TestIF2", null}, + {"TestIF3", null}, + {"TestIF4", null}, + {"TestIF5", null}, + {"TestIF6", null}, + {"TestIF7", "TestIF7.TestClass7"}, + {"TestIF8", "TestIF8.TestClass8"}, + {"TestIF9", null}, + {"TestIF10", null}, + {"TestIF11", null}, + {"TestIF12", null}, + {"TestIF1A", null}, + {"TestIF1B", null}, + {"TestIF1C", null}, + {"TestIF1D", null}, + {"TestIF15", null}, + {"TestIF16", null}, + {"TestIF17", null},}; + } + + @DataProvider + static Object[][] testCasesAll() { + List<Object[]> result = Lists.newArrayList(); + result.addAll(Arrays.asList(testClasses())); + result.addAll(Arrays.asList(testInterfaces())); + return result.toArray(new Object[result.size()][]); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/reflect/DefaultStaticTest/helper/Declared.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Helper class used for testing default/static method + * + * @author Yong Lu + */ + +package helper; + +public enum Declared { + YES, + NO +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/reflect/DefaultStaticTest/helper/Mod.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * Helper class used for testing default/static method + * + * @author Yong Lu + */ + +package helper; + +public enum Mod { + DEFAULT, + STATIC, + REGULAR, + ABSTRACT +}
--- a/test/java/lang/reflect/Method/DefaultMethodModeling.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/lang/reflect/Method/DefaultMethodModeling.java Wed Aug 07 19:56:20 2013 -0700 @@ -43,7 +43,7 @@ SuperIwithDefault.class, SuperIwithDefaultChild.class, Base.class, Combo1.class, Combo2.class, SonSuperIwithDefault.class, DaughterSuperIwithDefault.class, GrandchildSuperIwithDefault.class, D.class, - B.class, C.class + B.class, C.class, B1.class, D1.class }; for(Class<?> clazz : classes) { @@ -202,6 +202,17 @@ public void quux(){} } +class D1 implements SonSuperIwithDefault, DaughterSuperIwithDefault { + @ExpectedModel(declaringClass=D1.class) + public void foo(){} + + @ExpectedModel(declaringClass=D1.class) + public void baz(){} + + @ExpectedModel(declaringClass=D1.class) + public void quux(){} +} + // -=-=-=- // What does re-abstraction look like? @@ -222,3 +233,21 @@ @ExpectedModel(declaringClass=C.class) public void bar(){} } + +abstract class A1 implements SonSuperIwithDefault { + @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class) + public abstract void baz(); + + @ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class) + public abstract void foo(); +} + +class B1 extends A1 { + @ExpectedModel(declaringClass=B1.class) + @Override + public void foo(){;} + + @ExpectedModel(declaringClass=B1.class) + @Override + public void baz(){} +}
--- a/test/java/lang/reflect/Method/IsDefaultTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/lang/reflect/Method/IsDefaultTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -42,6 +42,12 @@ classList.add(TestType2.class); classList.add(TestType3.class); classList.add(TestType4.class); + classList.add(TestType2.nestedTestType2.class); + classList.add(TestType5.class); + classList.add(TestType5.nestedTestType5.class); + classList.add(TestType6.class); + classList.add(TestType6.nestedTestType6.class); + classList.add(TestType7.class); for(Class<?> clazz: classList) { for(Method method: clazz.getDeclaredMethods()) { @@ -78,11 +84,22 @@ @ExpectedIsDefault(true) default void bar() {}; // Default method + + @ExpectedIsDefault(true) + default void bar(int i) {}; // Default method + + @ExpectedIsDefault(true) + default void bar(String i) {}; // Default method } class TestType2 { @ExpectedIsDefault(false) void bar() {}; + + interface nestedTestType2 { + @ExpectedIsDefault(true) + default void nestedBar() {}; + } } class TestType3 implements TestType1 { @@ -92,6 +109,10 @@ @ExpectedIsDefault(false) @Override public void bar() {}; + + @ExpectedIsDefault(false) + @Override + public void bar(int i) {}; } @interface TestType4 { @@ -102,6 +123,51 @@ String anotherValue() default ""; } +interface TestType5 { + @ExpectedIsDefault(false) + abstract void aFoo(); + + @ExpectedIsDefault(false) + static void sFoo() {}; + + @ExpectedIsDefault(true) + public default void pBar() {}; + + @ExpectedIsDefault(true) + public default String sBar() {return "";}; + + interface nestedTestType5{ + @ExpectedIsDefault(false) + void nestedFoo(); + + @ExpectedIsDefault(true) + default void nestedBar() {}; + } +} + +class TestType6{ + interface nestedTestType6 { + @ExpectedIsDefault(true) + default void nestedBar() {}; + + @ExpectedIsDefault(false) + void nestedFoo(); + } + + @ExpectedIsDefault(false) + void foo(nestedTestType6 n) {} +} + +class TestType7 implements TestType6.nestedTestType6 { + + @ExpectedIsDefault(false) + public void nestedFoo() {} + + @ExpectedIsDefault(false) + @Override + public void nestedBar() {}; +} + @Retention(RetentionPolicy.RUNTIME) @interface ExpectedIsDefault { boolean value();
--- a/test/java/math/BigDecimal/CompareToTests.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/math/BigDecimal/CompareToTests.java Wed Aug 07 19:56:20 2013 -0700 @@ -53,12 +53,29 @@ {valueOf(5,-1), valueOf(2), ONE}, // Boundary and near boundary values - {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, - {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), ONE}, + {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MAX_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MAX_VALUE), ZERO}, + + {valueOf(Long.MAX_VALUE), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MIN_VALUE), ONE}, }; for (BigDecimal[] testCase : testCases) { @@ -69,8 +86,6 @@ int expected = testCase[2].intValue(); failures += compareToTest(a, b, expected); - failures += compareToTest(a_negate, b, -1); - failures += compareToTest(a, b_negate, 1); failures += compareToTest(a_negate, b_negate, -expected); } @@ -81,11 +96,11 @@ private static int compareToTest(BigDecimal a, BigDecimal b, int expected) { int result = a.compareTo(b); int failed = (result==expected) ? 0 : 1; - if (result == 1) { + if (failed == 1) { System.err.println("(" + a + ").compareTo(" + b + ") => " + result + "\n\tExpected " + expected); } - return result; + return failed; } public static void main(String argv[]) {
--- a/test/java/math/BigInteger/CompareToTests.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/math/BigInteger/CompareToTests.java Wed Aug 07 19:56:20 2013 -0700 @@ -24,20 +24,23 @@ /* * @test * @bug 6473768 - * @summary Tests of BigDecimal.compareTo + * @summary Tests of BigInteger.compareTo * @author Joseph D. Darcy */ import java.math.*; -import static java.math.BigDecimal.*; +import static java.math.BigInteger.*; public class CompareToTests { private static int compareToTests() { int failures = 0; - final BigDecimal MINUS_ONE = BigDecimal.ONE.negate(); + final BigInteger MINUS_ONE = BigInteger.ONE.negate(); + final BigInteger TWO_POW_126 = ONE.shiftLeft(126); + final BigInteger TWO_POW_127 = ONE.shiftLeft(127); + final BigInteger TWO_POW_128 = ONE.shiftLeft(128); // First operand, second operand, expected compareTo result - BigDecimal [][] testCases = { + BigInteger [][] testCases = { // Basics {valueOf(0), valueOf(0), ZERO}, {valueOf(0), valueOf(1), MINUS_ONE}, @@ -45,32 +48,56 @@ {valueOf(2), valueOf(1), ONE}, {valueOf(10), valueOf(10), ZERO}, - // Significands would compare differently than scaled value - {valueOf(2,1), valueOf(2), MINUS_ONE}, - {valueOf(2,-1), valueOf(2), ONE}, - {valueOf(1,1), valueOf(2), MINUS_ONE}, - {valueOf(1,-1), valueOf(2), ONE}, - {valueOf(5,-1), valueOf(2), ONE}, + // Various relative lengths of internal mag array. + {TWO_POW_127, TWO_POW_127, ZERO}, + {TWO_POW_127.negate(), TWO_POW_127, MINUS_ONE}, + + {TWO_POW_128.or(TWO_POW_126), TWO_POW_128, ONE}, + {TWO_POW_128.or(TWO_POW_126), TWO_POW_128.negate(), ONE}, + + {TWO_POW_128, TWO_POW_128.or(TWO_POW_126), MINUS_ONE}, + {TWO_POW_128.negate(), TWO_POW_128.or(TWO_POW_126), MINUS_ONE}, + + {TWO_POW_127, TWO_POW_128, MINUS_ONE}, + {TWO_POW_127.negate(), TWO_POW_128, MINUS_ONE}, + + {TWO_POW_128, TWO_POW_127, ONE}, + {TWO_POW_128.negate(), TWO_POW_127, MINUS_ONE}, + + // Long boundary and near boundary values + {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, - // Boundary and near boundary values - {valueOf(Long.MAX_VALUE), valueOf(Long.MAX_VALUE), ZERO}, - {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, - {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, - {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), ONE}, + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MAX_VALUE), MINUS_ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MAX_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MAX_VALUE), MINUS_ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MAX_VALUE), ZERO}, + + {valueOf(Long.MAX_VALUE), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MAX_VALUE-1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MAX_VALUE-1).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE), valueOf(Long.MIN_VALUE), ZERO}, + {valueOf(Long.MIN_VALUE).negate(), valueOf(Long.MIN_VALUE), ONE}, + + {valueOf(Long.MIN_VALUE+1), valueOf(Long.MIN_VALUE), ONE}, + {valueOf(Long.MIN_VALUE+1).negate(), valueOf(Long.MIN_VALUE), ONE}, }; - for (BigDecimal[] testCase : testCases) { - BigDecimal a = testCase[0]; - BigDecimal a_negate = a.negate(); - BigDecimal b = testCase[1]; - BigDecimal b_negate = b.negate(); + for (BigInteger[] testCase : testCases) { + BigInteger a = testCase[0]; + BigInteger a_negate = a.negate(); + BigInteger b = testCase[1]; + BigInteger b_negate = b.negate(); int expected = testCase[2].intValue(); failures += compareToTest(a, b, expected); - failures += compareToTest(a_negate, b, -1); - failures += compareToTest(a, b_negate, 1); failures += compareToTest(a_negate, b_negate, -expected); } @@ -78,14 +105,14 @@ return failures; } - private static int compareToTest(BigDecimal a, BigDecimal b, int expected) { + private static int compareToTest(BigInteger a, BigInteger b, int expected) { int result = a.compareTo(b); int failed = (result==expected) ? 0 : 1; - if (result == 1) { + if (failed == 1) { System.err.println("(" + a + ").compareTo(" + b + ") => " + result + "\n\tExpected " + expected); } - return result; + return failed; } public static void main(String argv[]) {
--- a/test/java/net/NetworkInterface/IndexTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/net/NetworkInterface/IndexTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -27,7 +27,10 @@ */ import java.net.*; +import java.util.Arrays; +import java.util.Collections; import java.util.Enumeration; +import static java.lang.System.out; public class IndexTest { public static void main(String[] args) throws Exception { @@ -39,12 +42,17 @@ if (index >= 0) { NetworkInterface nif2 = NetworkInterface.getByIndex(index); if (! nif.equals(nif2)) { + out.printf("%nExpected interfaces to be the same, but got:%n"); + displayInterfaceInformation(nif); + displayInterfaceInformation(nif2); throw new RuntimeException("both interfaces should be equal"); } } } try { nif = NetworkInterface.getByIndex(-1); + out.printf("%ngetByIndex(-1) should have thrown, but instead returned:%n"); + displayInterfaceInformation(nif); throw new RuntimeException("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException e) { // OK @@ -52,7 +60,29 @@ // In all likelyhood, this interface should not exist. nif = NetworkInterface.getByIndex(Integer.MAX_VALUE - 1); if (nif != null) { + out.printf("%ngetByIndex(MAX_VALUE - 1), expected null, got:%n"); + displayInterfaceInformation(nif); throw new RuntimeException("getByIndex() should have returned null"); } } + + static void displayInterfaceInformation(NetworkInterface netint) throws SocketException { + out.printf("Display name: %s%n", netint.getDisplayName()); + out.printf("Name: %s%n", netint.getName()); + Enumeration<InetAddress> inetAddresses = netint.getInetAddresses(); + + for (InetAddress inetAddress : Collections.list(inetAddresses)) + out.printf("InetAddress: %s%n", inetAddress); + + out.printf("Up? %s%n", netint.isUp()); + out.printf("Loopback? %s%n", netint.isLoopback()); + out.printf("PointToPoint? %s%n", netint.isPointToPoint()); + out.printf("Supports multicast? %s%n", netint.supportsMulticast()); + out.printf("Virtual? %s%n", netint.isVirtual()); + out.printf("Hardware address: %s%n", + Arrays.toString(netint.getHardwareAddress())); + out.printf("MTU: %s%n", netint.getMTU()); + out.printf("Index: %s%n", netint.getIndex()); + out.printf("%n"); + } }
--- a/test/java/nio/file/Files/BytesAndLines.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/nio/file/Files/BytesAndLines.java Wed Aug 07 19:56:20 2013 -0700 @@ -22,7 +22,7 @@ */ /* @test - * @bug 7006126 + * @bug 7006126 8020669 * @summary Unit test for methods for Files readAllBytes, readAllLines and * and write methods. */ @@ -82,6 +82,16 @@ write(file, lines, Charset.defaultCharset(), opts); throw new RuntimeException("NullPointerException expected"); } catch (NullPointerException ignore) { } + + // read from procfs + if (System.getProperty("os.name").equals("Linux")) { + // Refer to the Linux proc(5) man page for details about /proc/self/stat file + // procfs reports it to be zero sized, even though data can be read from it + String statFile = "/proc/self/stat"; + Path pathStat = Paths.get(statFile); + byte[] data = Files.readAllBytes(pathStat); + assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read"); + } } @@ -174,6 +184,16 @@ throw new RuntimeException("NullPointerException expected"); } catch (NullPointerException ignore) { } + // read from procfs + if (System.getProperty("os.name").equals("Linux")) { + // Refer to the Linux proc(5) man page for details about /proc/self/status file + // procfs reports this file to be zero sized, even though data can be read from it + String statusFile = "/proc/self/status"; + Path pathStatus = Paths.get(statusFile); + lines = Files.readAllLines(pathStatus, US_ASCII); + assertTrue(lines.size() > 0, "Files.readAllLines('" + pathStatus + "') failed to read"); + } + } finally { delete(tmpfile); } @@ -242,7 +262,6 @@ } finally { delete(tmpfile); } - } static void assertTrue(boolean expr, String errmsg) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Security/AddProvider.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, 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 8001319 + * @summary check that SecurityPermission insertProvider permission is enforced + * correctly + * @run main/othervm/policy=AddProvider.policy.1 AddProvider 1 + * @run main/othervm/policy=AddProvider.policy.2 AddProvider 2 + * @run main/othervm/policy=AddProvider.policy.3 AddProvider 3 + */ +import java.security.Provider; +import java.security.Security; + +public class AddProvider { + + public static void main(String[] args) throws Exception { + boolean legacy = args[0].equals("2"); + Security.addProvider(new TestProvider("Test1")); + Security.insertProviderAt(new TestProvider("Test2"), 1); + try { + Security.addProvider(new TestProvider("Test3")); + if (legacy) { + throw new Exception("Expected SecurityException"); + } + } catch (SecurityException se) { + if (!legacy) { + throw se; + } + } + } + + private static class TestProvider extends Provider { + TestProvider(String name) { + super(name, 0.0, "Not for use in production systems!"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Security/AddProvider.policy.1 Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,7 @@ +grant codeBase "file:${{java.ext.dirs}}/*" { + permission java.security.AllPermission; +}; + +grant { + permission java.security.SecurityPermission "insertProvider"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Security/AddProvider.policy.2 Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,8 @@ +grant codeBase "file:${{java.ext.dirs}}/*" { + permission java.security.AllPermission; +}; + +grant { + permission java.security.SecurityPermission "insertProvider.Test1"; + permission java.security.SecurityPermission "insertProvider.Test2"; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/Security/AddProvider.policy.3 Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,7 @@ +grant codeBase "file:${{java.ext.dirs}}/*" { + permission java.security.AllPermission; +}; + +grant { + permission java.security.SecurityPermission "insertProvider.*"; +};
--- a/test/java/util/Formatter/Basic-X.java.template Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/Formatter/Basic-X.java.template Wed Aug 07 19:56:20 2013 -0700 @@ -1319,10 +1319,8 @@ Math.nextDown(DoubleConsts.MIN_NORMAL)); test("%.1a", "0x1.0p-1022", Math.nextDown(DoubleConsts.MIN_NORMAL)); - test("%.11a", "0x1.ffffffffffep-1023", - Double.parseDouble("0x0.fffffffffffp-1022")); - test("%.1a", "0x1.0p-1022", - Double.parseDouble("0x0.fffffffffffp-1022")); + test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022); + test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022); test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE); test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE); test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE); @@ -1336,19 +1334,50 @@ test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE); test("%.1a", "0x1.0p1024", Double.MAX_VALUE); - test("%.11a", "0x1.18000000000p0", Double.parseDouble("0x1.18p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.18p0")); + test("%.11a", "0x1.18000000000p0", 0x1.18p0); + test("%.1a", "0x1.2p0", 0x1.18p0); + + test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0); + test("%.1a", "0x1.2p0", 0x1.180000000001p0); + test("%.11a", "0x1.28000000000p0", 0x1.28p0); + test("%.1a", "0x1.2p0", 0x1.28p0); + + test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0); + test("%.1a", "0x1.3p0", 0x1.280000000001p0); + + test("%a", "0x0.123p-1022", 0x0.123p-1022); + test("%1.3a", "0x1.230p-1026", 0x0.123p-1022); + test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022); + test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022); + test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022); + test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022); - test("%.11a", "0x1.18000000000p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.1a", "0x1.2p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.11a", "0x1.28000000000p0", Double.parseDouble("0x1.28p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.28p0")); + test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022); + test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022); + test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022); + test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022); + test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022); + test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022); - test("%.11a", "0x1.28000000000p0", - Double.parseDouble("0x1.280000000001p0")); - test("%.1a", "0x1.3p0", Double.parseDouble("0x1.280000000001p0")); + test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022); + test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022); + test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022); + + test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL)); + + test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + test("%1.1a", "0x1.0p1024", Double.MAX_VALUE); + test("%1.2a", "0x1.00p1024", Double.MAX_VALUE); + test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE); + test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE); + test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE); + test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE); + test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + #end[double] //---------------------------------------------------------------------
--- a/test/java/util/Formatter/Basic.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/Formatter/Basic.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,7 +25,7 @@ * @summary Unit test for formatter * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 - * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 + * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 6476168 * * @run shell/timeout=240 Basic.sh */
--- a/test/java/util/Formatter/BasicDouble.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/Formatter/BasicDouble.java Wed Aug 07 19:56:20 2013 -0700 @@ -1319,10 +1319,8 @@ Math.nextDown(DoubleConsts.MIN_NORMAL)); test("%.1a", "0x1.0p-1022", Math.nextDown(DoubleConsts.MIN_NORMAL)); - test("%.11a", "0x1.ffffffffffep-1023", - Double.parseDouble("0x0.fffffffffffp-1022")); - test("%.1a", "0x1.0p-1022", - Double.parseDouble("0x0.fffffffffffp-1022")); + test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022); + test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022); test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE); test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE); test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE); @@ -1336,19 +1334,50 @@ test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE); test("%.1a", "0x1.0p1024", Double.MAX_VALUE); - test("%.11a", "0x1.18000000000p0", Double.parseDouble("0x1.18p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.18p0")); - - test("%.11a", "0x1.18000000000p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.1a", "0x1.2p0", - Double.parseDouble("0x1.180000000001p0")); - test("%.11a", "0x1.28000000000p0", Double.parseDouble("0x1.28p0")); - test("%.1a", "0x1.2p0", Double.parseDouble("0x1.28p0")); - - test("%.11a", "0x1.28000000000p0", - Double.parseDouble("0x1.280000000001p0")); - test("%.1a", "0x1.3p0", Double.parseDouble("0x1.280000000001p0")); + test("%.11a", "0x1.18000000000p0", 0x1.18p0); + test("%.1a", "0x1.2p0", 0x1.18p0); + + test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0); + test("%.1a", "0x1.2p0", 0x1.180000000001p0); + test("%.11a", "0x1.28000000000p0", 0x1.28p0); + test("%.1a", "0x1.2p0", 0x1.28p0); + + test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0); + test("%.1a", "0x1.3p0", 0x1.280000000001p0); + + test("%a", "0x0.123p-1022", 0x0.123p-1022); + test("%1.3a", "0x1.230p-1026", 0x0.123p-1022); + test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022); + test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022); + test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022); + test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022); + test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022); + test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022); + test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022); + test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022); + test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022); + + test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022); + test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022); + test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022); + test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022); + + test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL)); + + test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + test("%1.1a", "0x1.0p1024", Double.MAX_VALUE); + test("%1.2a", "0x1.00p1024", Double.MAX_VALUE); + test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE); + test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE); + test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE); + test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE); + test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE); + //---------------------------------------------------------------------
--- a/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -25,6 +25,7 @@ * @test * @summary Spliterator traversing and splitting tests * @run testng SpliteratorTraversingAndSplittingTest + * @bug 8020016 */ import org.testng.annotations.DataProvider; @@ -386,11 +387,23 @@ db.addCollection(CopyOnWriteArraySet::new); - if (size == 1) { + if (size == 0) { + db.addCollection(c -> Collections.<Integer>emptySet()); + db.addList(c -> Collections.<Integer>emptyList()); + } + else if (size == 1) { db.addCollection(c -> Collections.singleton(exp.get(0))); db.addCollection(c -> Collections.singletonList(exp.get(0))); } + { + Integer[] ai = new Integer[size]; + Arrays.fill(ai, 1); + db.add(String.format("Collections.nCopies(%d, 1)", exp.size()), + Arrays.asList(ai), + () -> Collections.nCopies(exp.size(), 1).spliterator()); + } + // Collections.synchronized/unmodifiable/checked wrappers db.addCollection(Collections::unmodifiableCollection); db.addCollection(c -> Collections.unmodifiableSet(new HashSet<>(c))); @@ -454,6 +467,13 @@ db.addMap(ConcurrentHashMap::new); db.addMap(ConcurrentSkipListMap::new); + + if (size == 0) { + db.addMap(m -> Collections.<Integer, Integer>emptyMap()); + } + else if (size == 1) { + db.addMap(m -> Collections.singletonMap(exp.get(0), exp.get(0))); + } } return spliteratorDataProvider = data.toArray(new Object[0][]);
--- a/test/java/util/concurrent/CompletableFuture/Basic.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/concurrent/CompletableFuture/Basic.java Wed Aug 07 19:56:20 2013 -0700 @@ -34,6 +34,8 @@ /* * @test * @bug 8005696 + * @run main Basic + * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 Basic * @summary Basic tests for CompletableFuture * @author Chris Hegarty */
--- a/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java Wed Aug 07 19:56:20 2013 -0700 @@ -22,6 +22,8 @@ */ package java.util.stream; +import org.testng.annotations.Test; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -154,6 +156,7 @@ Collection<T> exp = Collections.unmodifiableList(fromForEach); + testNullPointerException(supplier); testForEach(exp, supplier, boxingAdapter, asserter); testTryAdvance(exp, supplier, boxingAdapter, asserter); testMixedTryAdvanceForEach(exp, supplier, boxingAdapter, asserter); @@ -166,6 +169,31 @@ // + private static <T, S extends Spliterator<T>> void testNullPointerException(Supplier<S> s) { + S sp = s.get(); + // Have to check instances and use casts to avoid tripwire messages and + // directly test the primitive methods + if (sp instanceof Spliterator.OfInt) { + Spliterator.OfInt psp = (Spliterator.OfInt) sp; + executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((IntConsumer) null)); + executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((IntConsumer) null)); + } + else if (sp instanceof Spliterator.OfLong) { + Spliterator.OfLong psp = (Spliterator.OfLong) sp; + executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((LongConsumer) null)); + executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((LongConsumer) null)); + } + else if (sp instanceof Spliterator.OfDouble) { + Spliterator.OfDouble psp = (Spliterator.OfDouble) sp; + executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((DoubleConsumer) null)); + executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((DoubleConsumer) null)); + } + else { + executeAndCatch(NullPointerException.class, () -> sp.forEachRemaining(null)); + executeAndCatch(NullPointerException.class, () -> sp.tryAdvance(null)); + } + } + private static <T, S extends Spliterator<T>> void testForEach( Collection<T> exp, Supplier<S> supplier, @@ -573,6 +601,23 @@ } } + private static void executeAndCatch(Class<? extends Exception> expected, Runnable r) { + Exception caught = null; + try { + r.run(); + } + catch (Exception e) { + caught = e; + } + + assertNotNull(caught, + String.format("No Exception was thrown, expected an Exception of %s to be thrown", + expected.getName())); + assertTrue(expected.isInstance(caught), + String.format("Exception thrown %s not an instance of %s", + caught.getClass().getName(), expected.getName())); + } + static<U> void mixedTraverseAndSplit(Consumer<U> b, Spliterator<U> splTop) { Spliterator<U> spl1, spl2, spl3; splTop.tryAdvance(b);
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/stream/test/org/openjdk/tests/java/util/FillableStringTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -40,17 +40,17 @@ } public void testStringBuilder() { - String s = generate().collect(Collectors.toStringBuilder()).toString(); + String s = generate().collect(Collectors.joining()); assertEquals(s, "THREEFOURFIVE"); } public void testStringBuffer() { - String s = generate().collect(Collectors.toStringBuilder()).toString(); + String s = generate().collect(Collectors.joining()); assertEquals(s, "THREEFOURFIVE"); } public void testStringJoiner() { - String s = generate().collect(Collectors.toStringJoiner("-")).toString(); + String s = generate().collect(Collectors.joining("-")); assertEquals(s, "THREE-FOUR-FIVE"); } }
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -36,7 +36,6 @@ import java.util.stream.LambdaTestHelpers; import java.util.stream.OpTestCase; import java.util.stream.Stream; -import java.util.stream.StreamOpFlagTestHelper; import java.util.stream.StreamTestDataProvider; import java.util.stream.TestData; @@ -59,13 +58,14 @@ public class GroupByOpTest extends OpTestCase { public void testBypassCollect() { - Collector<Integer, Map<Boolean, List<Integer>>> collector - = Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)); + @SuppressWarnings("unchecked") + Collector<Integer, Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>> collector + = (Collector<Integer, Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>>) Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)); - Map<Boolean, List<Integer>> m = collector.resultSupplier().get(); + Map<Boolean, List<Integer>> m = collector.supplier().get(); int[] ints = countTo(10).stream().mapToInt(e -> (int) e).toArray(); for (int i : ints) - m = collector.accumulator().apply(m, i); + collector.accumulator().accept(m, i); assertEquals(2, m.keySet().size()); for(Collection<Integer> group : m.values()) { @@ -130,7 +130,7 @@ // - Total number of values equals size of data for (MapperData<Integer, ?> md : getMapperData(data)) { - Collector<Integer, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m); + Collector<Integer, ?, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m); Map<Object, List<Integer>> result = withData(data) .terminal(s -> s, s -> s.collect(tab))
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SummaryStatisticsTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -43,9 +43,9 @@ public class SummaryStatisticsTest extends OpTestCase { public void testIntStatistics() { List<IntSummaryStatistics> instances = new ArrayList<>(); - instances.add(countTo(1000).stream().collect(Collectors.toIntSummaryStatistics(i -> i))); + instances.add(countTo(1000).stream().collect(Collectors.summarizingInt(i -> i))); instances.add(countTo(1000).stream().mapToInt(i -> i).summaryStatistics()); - instances.add(countTo(1000).parallelStream().collect(Collectors.toIntSummaryStatistics(i -> i))); + instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingInt(i -> i))); instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics()); for (IntSummaryStatistics stats : instances) { @@ -58,9 +58,9 @@ public void testLongStatistics() { List<LongSummaryStatistics> instances = new ArrayList<>(); - instances.add(countTo(1000).stream().collect(Collectors.toLongSummaryStatistics(i -> i))); + instances.add(countTo(1000).stream().collect(Collectors.summarizingLong(i -> i))); instances.add(countTo(1000).stream().mapToLong(i -> i).summaryStatistics()); - instances.add(countTo(1000).parallelStream().collect(Collectors.toLongSummaryStatistics(i -> i))); + instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingLong(i -> i))); instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics()); for (LongSummaryStatistics stats : instances) { @@ -73,9 +73,9 @@ public void testDoubleStatistics() { List<DoubleSummaryStatistics> instances = new ArrayList<>(); - instances.add(countTo(1000).stream().collect(Collectors.toDoubleSummaryStatistics(i -> i))); + instances.add(countTo(1000).stream().collect(Collectors.summarizingDouble(i -> i))); instances.add(countTo(1000).stream().mapToDouble(i -> i).summaryStatistics()); - instances.add(countTo(1000).parallelStream().collect(Collectors.toDoubleSummaryStatistics(i -> i))); + instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingDouble(i -> i))); instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics()); for (DoubleSummaryStatistics stats : instances) {
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java Wed Aug 07 19:56:20 2013 -0700 @@ -23,13 +23,17 @@ package org.openjdk.tests.java.util.stream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; @@ -53,7 +57,10 @@ import static java.util.stream.Collectors.partitioningBy; import static java.util.stream.Collectors.reducing; import static java.util.stream.Collectors.toCollection; +import static java.util.stream.Collectors.toConcurrentMap; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static java.util.stream.Collectors.toSet; import static java.util.stream.LambdaTestHelpers.assertContents; import static java.util.stream.LambdaTestHelpers.assertContentsUnordered; import static java.util.stream.LambdaTestHelpers.mDoubler; @@ -65,16 +72,6 @@ */ @SuppressWarnings({"rawtypes", "unchecked"}) public class TabulatorsTest extends OpTestCase { - // There are 8 versions of groupingBy: - // groupingBy: { map supplier, not } x { downstream collector, not } x { concurrent, not } - // There are 2 versions of partition: { map supplier, not } - // There are 4 versions of toMap - // mappedTo(function, mapSupplier?, mergeFunction?) - // Each variety needs at least one test - // Plus a variety of multi-level tests (groupBy(..., partition), partition(..., groupBy)) - // Plus negative tests for mapping to null - // Each test should be matched by a nest of asserters (see TabulationAssertion...) - private static abstract class TabulationAssertion<T, U> { abstract void assertValue(U value, @@ -101,7 +98,7 @@ boolean ordered) throws ReflectiveOperationException { if (!clazz.isAssignableFrom(map.getClass())) fail(String.format("Class mismatch in GroupedMapAssertion: %s, %s", clazz, map.getClass())); - assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(Collectors.toSet())); + assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(toSet())); for (Map.Entry<K, ? extends V> entry : map.entrySet()) { K key = entry.getKey(); downstream.assertValue(entry.getValue(), @@ -111,6 +108,39 @@ } } + static class ToMapAssertion<T, K, V, M extends Map<K,V>> extends TabulationAssertion<T, M> { + private final Class<? extends Map> clazz; + private final Function<T, K> keyFn; + private final Function<T, V> valueFn; + private final BinaryOperator<V> mergeFn; + + ToMapAssertion(Function<T, K> keyFn, + Function<T, V> valueFn, + BinaryOperator<V> mergeFn, + Class<? extends Map> clazz) { + this.clazz = clazz; + this.keyFn = keyFn; + this.valueFn = valueFn; + this.mergeFn = mergeFn; + } + + @Override + void assertValue(M map, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException { + Set<K> uniqueKeys = source.get().map(keyFn).collect(toSet()); + assertTrue(clazz.isAssignableFrom(map.getClass())); + assertEquals(uniqueKeys, map.keySet()); + source.get().forEach(t -> { + K key = keyFn.apply(t); + V v = source.get() + .filter(e -> key.equals(keyFn.apply(e))) + .map(valueFn) + .reduce(mergeFn) + .get(); + assertEquals(map.get(key), v); + }); + } + } + static class PartitionAssertion<T, D> extends TabulationAssertion<T, Map<Boolean,D>> { private final Predicate<T> predicate; private final TabulationAssertion<T,D> downstream; @@ -204,7 +234,7 @@ private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) { return (act, exp, ord, par) -> { - if (par & (!ordered || !ord)) { + if (par && (!ordered || !ord)) { TabulatorsTest.nestedMapEqualityAssertion(act, exp); } else { @@ -215,7 +245,7 @@ private<T, M extends Map> void exerciseMapTabulation(TestData<T, Stream<T>> data, - Collector<T, ? extends M> collector, + Collector<T, ?, ? extends M> collector, TabulationAssertion<T, M> assertion) throws ReflectiveOperationException { boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED); @@ -248,6 +278,172 @@ assertEquals(o1, o2); } + private<T, R> void assertCollect(TestData.OfRef<T> data, + Collector<T, ?, R> collector, + Function<Stream<T>, R> streamReduction) { + R check = streamReduction.apply(data.stream()); + withData(data).terminal(s -> s.collect(collector)).expectedResult(check).exercise(); + } + + @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class) + public void testReduce(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException { + assertCollect(data, Collectors.reducing(0, Integer::sum), + s -> s.reduce(0, Integer::sum)); + assertCollect(data, Collectors.reducing(Integer.MAX_VALUE, Integer::min), + s -> s.min(Integer::compare).orElse(Integer.MAX_VALUE)); + assertCollect(data, Collectors.reducing(Integer.MIN_VALUE, Integer::max), + s -> s.max(Integer::compare).orElse(Integer.MIN_VALUE)); + + assertCollect(data, Collectors.reducing(Integer::sum), + s -> s.reduce(Integer::sum)); + assertCollect(data, Collectors.minBy(Comparator.naturalOrder()), + s -> s.min(Integer::compare)); + assertCollect(data, Collectors.maxBy(Comparator.naturalOrder()), + s -> s.max(Integer::compare)); + + assertCollect(data, Collectors.reducing(0, x -> x*2, Integer::sum), + s -> s.map(x -> x*2).reduce(0, Integer::sum)); + + assertCollect(data, Collectors.summingLong(x -> x * 2L), + s -> s.map(x -> x*2L).reduce(0L, Long::sum)); + assertCollect(data, Collectors.summingInt(x -> x * 2), + s -> s.map(x -> x*2).reduce(0, Integer::sum)); + assertCollect(data, Collectors.summingDouble(x -> x * 2.0d), + s -> s.map(x -> x * 2.0d).reduce(0.0d, Double::sum)); + + assertCollect(data, Collectors.averagingInt(x -> x * 2), + s -> s.mapToInt(x -> x * 2).average().orElse(0)); + assertCollect(data, Collectors.averagingLong(x -> x * 2), + s -> s.mapToLong(x -> x * 2).average().orElse(0)); + assertCollect(data, Collectors.averagingDouble(x -> x * 2), + s -> s.mapToDouble(x -> x * 2).average().orElse(0)); + + // Test explicit Collector.of + Collector<Integer, long[], Double> avg2xint = Collector.of(() -> new long[2], + (a, b) -> { + a[0] += b * 2; + a[1]++; + }, + (a, b) -> { + a[0] += b[0]; + a[1] += b[1]; + return a; + }, + a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]); + assertCollect(data, avg2xint, + s -> s.mapToInt(x -> x * 2).average().orElse(0)); + } + + @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class) + public void testJoin(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException { + withData(data) + .terminal(s -> s.map(Object::toString).collect(Collectors.joining())) + .expectedResult(join(data, "")) + .exercise(); + + Collector<String, StringBuilder, String> likeJoining = Collector.of(StringBuilder::new, StringBuilder::append, (sb1, sb2) -> sb1.append(sb2.toString()), StringBuilder::toString); + withData(data) + .terminal(s -> s.map(Object::toString).collect(likeJoining)) + .expectedResult(join(data, "")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString).collect(Collectors.joining(","))) + .expectedResult(join(data, ",")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",", "[", "]"))) + .expectedResult("[" + join(data, ",") + "]") + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString) + .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) + .toString()) + .expectedResult(join(data, "")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString) + .collect(() -> new StringJoiner(","), + (sj, cs) -> sj.add(cs), + (j1, j2) -> j1.merge(j2)) + .toString()) + .expectedResult(join(data, ",")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString) + .collect(() -> new StringJoiner(",", "[", "]"), + (sj, cs) -> sj.add(cs), + (j1, j2) -> j1.merge(j2)) + .toString()) + .expectedResult("[" + join(data, ",") + "]") + .exercise(); + } + + private<T> String join(TestData.OfRef<T> data, String delim) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (T i : data) { + if (!first) + sb.append(delim); + sb.append(i.toString()); + first = false; + } + return sb.toString(); + } + + @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class) + public void testSimpleToMap(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException { + Function<Integer, Integer> keyFn = i -> i * 2; + Function<Integer, Integer> valueFn = i -> i * 4; + + List<Integer> dataAsList = Arrays.asList(data.stream().toArray(Integer[]::new)); + Set<Integer> dataAsSet = new HashSet<>(dataAsList); + + BinaryOperator<Integer> sum = Integer::sum; + for (BinaryOperator<Integer> op : Arrays.asList((u, v) -> u, + (u, v) -> v, + sum)) { + try { + exerciseMapTabulation(data, toMap(keyFn, valueFn), + new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class)); + if (dataAsList.size() != dataAsSet.size()) + fail("Expected ISE on input with duplicates"); + } + catch (IllegalStateException e) { + if (dataAsList.size() == dataAsSet.size()) + fail("Expected no ISE on input without duplicates"); + } + + exerciseMapTabulation(data, toMap(keyFn, valueFn, op), + new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class)); + + exerciseMapTabulation(data, toMap(keyFn, valueFn, op, TreeMap::new), + new ToMapAssertion<>(keyFn, valueFn, op, TreeMap.class)); + } + + // For concurrent maps, only use commutative merge functions + try { + exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn), + new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class)); + if (dataAsList.size() != dataAsSet.size()) + fail("Expected ISE on input with duplicates"); + } + catch (IllegalStateException e) { + if (dataAsList.size() == dataAsSet.size()) + fail("Expected no ISE on input without duplicates"); + } + + exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn, sum), + new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class)); + + exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn, sum, ConcurrentSkipListMap::new), + new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentSkipListMap.class)); + } + @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class) public void testSimpleGroupBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException { Function<Integer, Integer> classifier = i -> i % 3;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/crypto/dsig/TransformService/NullParent.java Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, 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 8022120 + * @summary check that the init and marshalParams methods throw + * NullPointerException when the parent parameter is null + */ + +import javax.xml.crypto.dsig.CanonicalizationMethod; +import javax.xml.crypto.dsig.Transform; +import javax.xml.crypto.dsig.TransformService; + +public class NullParent { + + public static void main(String[] args) throws Exception { + String[] transforms = new String[] + { Transform.BASE64, Transform.ENVELOPED, Transform.XPATH, + Transform.XPATH2, Transform.XSLT, + CanonicalizationMethod.EXCLUSIVE, + CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, + CanonicalizationMethod.INCLUSIVE, + CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS }; + + for (String transform : transforms) { + System.out.println("Testing " + transform); + TransformService ts = TransformService.getInstance(transform, + "DOM"); + try { + ts.init(null, null); + throw new Exception("init must throw NullPointerException " + + "when the parent parameter is null"); + } catch (NullPointerException npe) { } + try { + ts.marshalParams(null, null); + throw new Exception("marshalParams must throw " + + "NullPointerException when the parent " + + "parameter is null"); + } catch (NullPointerException npe) { } + } + } +}
--- a/test/jdk/lambda/MethodReferenceTestInstanceMethod.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/jdk/lambda/MethodReferenceTestInstanceMethod.java Wed Aug 07 19:56:20 2013 -0700 @@ -47,7 +47,7 @@ } public void testStringBuffer() { - String s = generate().collect(Collectors.toStringBuilder()).toString(); + String s = generate().collect(Collectors.joining()); assertEquals(s, "THREEFOURFIVE"); }
--- a/test/jdk/lambda/separate/TestHarness.java Wed Aug 07 19:52:47 2013 -0700 +++ b/test/jdk/lambda/separate/TestHarness.java Wed Aug 07 19:56:20 2013 -0700 @@ -119,7 +119,7 @@ Class stub = new Class(specimen.getName(), cm); String params = - Arrays.asList(args).stream().collect(Collectors.toStringJoiner(", ")).toString(); + Arrays.asList(args).stream().collect(Collectors.joining(", ")).toString(); ConcreteMethod sm = new ConcreteMethod( method.getReturnType(), method.getName(), @@ -150,7 +150,7 @@ null, Arrays.asList((Method)method)); Class cstub = new Class(specimen.getName()); - String params = Arrays.asList(args).stream().collect(Collectors.toStringJoiner(", ")).toString(); + String params = Arrays.asList(args).stream().collect(Collectors.joining(", ")).toString(); ConcreteMethod sm = new ConcreteMethod( "int", SourceModel.stdMethodName,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/tools/jarsigner/collator.sh Wed Aug 07 19:56:20 2013 -0700 @@ -0,0 +1,76 @@ +# +# Copyright (c) 2013, 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 8021789 +# @summary jarsigner parses alias as command line option (depending on locale) +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +F=collator +KS=collator.jks +JFILE=collator.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ + -keystore $KS" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" + +rm $F $KS $JFILE 2> /dev/null + +echo 12345 > $F +$JAR cvf $JFILE $F + +ERR="" + +$KT -alias debug -dname CN=debug -genkey -validity 300 || ERR="$ERR 1" + +# use "debug" as alias name +$JARSIGNER $JFILE debug || ERR="$ERR 2" + +# use "" as alias name (although there will be a warning) +$JARSIGNER -verify $JFILE "" || ERR="$ERR 3" + +if [ "$ERR" = "" ]; then + exit 0 +else + echo "ERR is $ERR" + exit 1 +fi + +