Mercurial > hg > openjdk > jdk8 > jdk
changeset 9099:eef10feca8ca
Merge
author | lana |
---|---|
date | Thu, 06 Feb 2014 13:28:20 -0800 |
parents | 3c9473004f38 (diff) ab6e7bb8ff9f (current diff) |
children | 80568a19aab7 |
files | |
diffstat | 49 files changed, 3754 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Wed Jan 22 16:15:39 2014 +0400 +++ b/.hgtags Thu Feb 06 13:28:20 2014 -0800 @@ -246,3 +246,7 @@ e1499442453b6b70af6c2b496fa6d364f68c1d12 jdk8-b122 484e16c0a040efeccbe449d163e9c185e6c2b4db jdk8-b123 ae303640bc1cca06f1c6ac887e6b523ceeb425a6 jdk8-b124 +ae303640bc1cca06f1c6ac887e6b523ceeb425a6 jdk8-b125 +a9088d517f2fa9919886d3d95023c518b59172b8 jdk8-b126 +fbf251b8ef8a4a2aa1fd58efc8d0d5c8e2fd582b jdk8-b127 +f644211c59fd7c1d0c81239c55b31e1d377d7650 jdk8-b128
--- a/THIRD_PARTY_README Wed Jan 22 16:15:39 2014 +0400 +++ b/THIRD_PARTY_README Thu Feb 06 13:28:20 2014 -0800 @@ -1400,7 +1400,7 @@ ------------------------------------------------------------------------------- %% This notice is provided with respect to Little CMS 2.4, which may be -included with OpenJDK 8. +included with JRE 8, JDK 8, and OpenJDK 8. --- begin of LICENSE ---
--- a/make/Images.gmk Wed Jan 22 16:15:39 2014 +0400 +++ b/make/Images.gmk Thu Feb 06 13:28:20 2014 -0800 @@ -321,9 +321,13 @@ ################################################################################ # /man dir +# +# All variables in this section are assigned with simple =, without :, to enable +# more selective overriding from the custom version of this file. +# # Avoid evaluating this whole section on windows for speed and stability ifneq ($(OPENJDK_TARGET_OS), windows) - JRE_MAN_PAGES := \ + JRE_MAN_PAGES = \ java.1 \ jjs.1 \ keytool.1 \ @@ -374,28 +378,20 @@ wsimport.1 \ xjc.1 - ifndef OPENJDK - JDK_MAN_PAGES += \ - jvisualvm.1 \ - jmc.1 \ - # - endif - # This variable is potentially overridden in the closed makefile. MAN_SRC_BASEDIR ?= $(JDK_TOPDIR)/src ifeq ($(OPENJDK_TARGET_OS), linux) - MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/linux/doc - MAN1_SUBDIR := man + MAN_SRC_DIR = $(MAN_SRC_BASEDIR)/linux/doc + MAN1_SUBDIR = man endif ifeq ($(OPENJDK_TARGET_OS), solaris) - MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/solaris/doc - MAN1_SUBDIR := sun/man/man1 - JDK_MAN_PAGES := $(filter-out jmc.1, $(JDK_MAN_PAGES)) + MAN_SRC_DIR = $(MAN_SRC_BASEDIR)/solaris/doc + MAN1_SUBDIR = sun/man/man1 endif ifeq ($(OPENJDK_TARGET_OS), macosx) - MAN_SRC_DIR := $(MAN_SRC_BASEDIR)/bsd/doc - MAN1_SUBDIR := man + MAN_SRC_DIR = $(MAN_SRC_BASEDIR)/bsd/doc + MAN1_SUBDIR = man endif $(JRE_IMAGE_DIR)/man/man1/%: $(MAN_SRC_DIR)/$(MAN1_SUBDIR)/% @@ -470,33 +466,33 @@ endif ifeq ($(OPENJDK_TARGET_OS), linux) - JRE_MAN_PAGE_LIST := $(addprefix $(JRE_IMAGE_DIR)/man/man1/, $(JRE_MAN_PAGES)) \ + JRE_MAN_PAGE_LIST = $(addprefix $(JRE_IMAGE_DIR)/man/man1/, $(JRE_MAN_PAGES)) \ $(addprefix $(JRE_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JRE_MAN_PAGES)) \ $(JRE_IMAGE_DIR)/man/ja - JDK_MAN_PAGE_LIST := $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \ + JDK_MAN_PAGE_LIST = $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \ $(addprefix $(JDK_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JDK_MAN_PAGES)) \ $(JDK_IMAGE_DIR)/man/ja endif ifeq ($(OPENJDK_TARGET_OS), solaris) - JRE_MAN_PAGE_LIST := $(addprefix $(JRE_IMAGE_DIR)/man/man1/, $(JRE_MAN_PAGES)) \ + JRE_MAN_PAGE_LIST = $(addprefix $(JRE_IMAGE_DIR)/man/man1/, $(JRE_MAN_PAGES)) \ $(addprefix $(JRE_IMAGE_DIR)/man/ja/man1/, $(JRE_MAN_PAGES)) \ $(addprefix $(JRE_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JRE_MAN_PAGES)) \ $(addprefix $(JRE_IMAGE_DIR)/man/ja_JP.PCK/man1/, $(JRE_MAN_PAGES)) - JDK_MAN_PAGE_LIST := $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \ + JDK_MAN_PAGE_LIST = $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \ $(addprefix $(JDK_IMAGE_DIR)/man/ja/man1/, $(JDK_MAN_PAGES)) \ $(addprefix $(JDK_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JDK_MAN_PAGES)) \ $(addprefix $(JDK_IMAGE_DIR)/man/ja_JP.PCK/man1/, $(JDK_MAN_PAGES)) endif ifeq ($(OPENJDK_TARGET_OS), macosx) - JRE_MAN_PAGE_LIST := $(addprefix $(JRE_IMAGE_DIR)/man/man1/, $(JRE_MAN_PAGES)) \ + JRE_MAN_PAGE_LIST = $(addprefix $(JRE_IMAGE_DIR)/man/man1/, $(JRE_MAN_PAGES)) \ $(addprefix $(JRE_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JRE_MAN_PAGES)) \ $(JRE_IMAGE_DIR)/man/ja - JDK_MAN_PAGE_LIST := $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \ + JDK_MAN_PAGE_LIST = $(addprefix $(JDK_IMAGE_DIR)/man/man1/, $(JDK_MAN_PAGES)) \ $(addprefix $(JDK_IMAGE_DIR)/man/ja_JP.UTF-8/man1/, $(JDK_MAN_PAGES)) \ $(JDK_IMAGE_DIR)/man/ja endif @@ -751,6 +747,13 @@ endif ################################################################################ + +# Include the custom makefile right here, after all variables have been defined +# so that they may be overridden, but before the main targets are declared, so +# that overriding has an effect. +-include $(CUSTOM_MAKE_DIR)/Images.gmk + +################################################################################ # Main targets jre-image: $(JRE_BIN_TARGETS) $(JRE_LIB_TARGETS) $(JRE_IMAGE_DIR)/lib/applet \ @@ -800,4 +803,3 @@ .PHONY: default images jre-image jdk-image --include $(CUSTOM_MAKE_DIR)/Images.gmk
--- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Thu Feb 06 13:28:20 2014 -0800 @@ -114,6 +114,11 @@ Class<?>[] markerInterfaces, MethodType[] additionalBridges) throws LambdaConversionException { + if ((caller.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) { + throw new LambdaConversionException(String.format( + "Invalid caller: %s", + caller.lookupClass().getName())); + } this.targetClass = caller.lookupClass(); this.invokedType = invokedType; @@ -221,6 +226,13 @@ String.format("Invalid receiver type %s; not a subtype of implementation type %s", receiverClass, implDefiningClass)); } + + Class<?> implReceiverClass = implMethod.type().parameterType(0); + if (implReceiverClass != implDefiningClass && !implReceiverClass.isAssignableFrom(receiverClass)) { + throw new LambdaConversionException( + String.format("Invalid receiver type %s; not a subtype of implementation receiver type %s", + receiverClass, implReceiverClass)); + } } else { // no receiver capturedStart = 0; @@ -256,11 +268,17 @@ (implKind == MethodHandleInfo.REF_newInvokeSpecial) ? implDefiningClass : implMethodType.returnType(); + Class<?> samReturnType = samMethodType.returnType(); if (!isAdaptableToAsReturn(actualReturnType, expectedType)) { throw new LambdaConversionException( String.format("Type mismatch for lambda return: %s is not convertible to %s", actualReturnType, expectedType)); } + if (!isAdaptableToAsReturn(expectedType, samReturnType)) { + throw new LambdaConversionException( + String.format("Type mismatch for lambda expected return: %s is not convertible to %s", + expectedType, samReturnType)); + } } /**
--- a/src/share/classes/java/util/jar/JarFile.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/java/util/jar/JarFile.java Thu Feb 06 13:28:20 2014 -0800 @@ -40,6 +40,7 @@ import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.misc.SharedSecrets; +import sun.security.util.SignatureFileVerifier; /** * The <code>JarFile</code> class is used to read the contents of a jar file @@ -364,11 +365,13 @@ String[] names = getMetaInfEntryNames(); if (names != null) { for (int i = 0; i < names.length; i++) { - JarEntry e = getJarEntry(names[i]); - if (e == null) { - throw new JarException("corrupted jar file"); - } - if (!e.isDirectory()) { + String uname = names[i].toUpperCase(Locale.ENGLISH); + if (MANIFEST_NAME.equals(uname) + || SignatureFileVerifier.isBlockOrSF(uname)) { + JarEntry e = getJarEntry(names[i]); + if (e == null) { + throw new JarException("corrupted jar file"); + } if (mev == null) { mev = new ManifestEntryVerifier (getManifestFromReference());
--- a/src/share/classes/java/util/stream/DoubleStream.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/java/util/stream/DoubleStream.java Thu Feb 06 13:28:20 2014 -0800 @@ -150,10 +150,11 @@ /** * Returns a stream consisting of the results of replacing each element of - * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. (If the result of the mapping - * function is {@code null}, this is treated as if the result was an empty - * stream.) + * this stream with the contents of a mapped stream produced by applying + * the provided mapping function to each element. Each mapped stream is + * {@link java.util.stream.BaseStream#close() closed} after its contents + * have been placed into this stream. (If a mapped stream is {@code null} + * an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>.
--- a/src/share/classes/java/util/stream/IntStream.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/java/util/stream/IntStream.java Thu Feb 06 13:28:20 2014 -0800 @@ -146,10 +146,11 @@ /** * Returns a stream consisting of the results of replacing each element of - * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. (If the result of the mapping - * function is {@code null}, this is treated as if the result was an empty - * stream.) + * this stream with the contents of a mapped stream produced by applying + * the provided mapping function to each element. Each mapped stream is + * {@link java.util.stream.BaseStream#close() closed} after its contents + * have been placed into this stream. (If a mapped stream is {@code null} + * an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>.
--- a/src/share/classes/java/util/stream/LongStream.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/java/util/stream/LongStream.java Thu Feb 06 13:28:20 2014 -0800 @@ -151,10 +151,11 @@ /** * Returns a stream consisting of the results of replacing each element of - * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. (If the result of the mapping - * function is {@code null}, this is treated as if the result was an empty - * stream.) + * this stream with the contents of a mapped stream produced by applying + * the provided mapping function to each element. Each mapped stream is + * {@link java.util.stream.BaseStream#close() closed} after its contents + * have been placed into this stream. (If a mapped stream is {@code null} + * an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>.
--- a/src/share/classes/java/util/stream/Stream.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/java/util/stream/Stream.java Thu Feb 06 13:28:20 2014 -0800 @@ -227,10 +227,11 @@ /** * Returns a stream consisting of the results of replacing each element of - * this stream with the contents of the stream produced by applying the - * provided mapping function to each element. (If the result of the mapping - * function is {@code null}, this is treated as if the result was an empty - * stream.) + * this stream with the contents of a mapped stream produced by applying + * the provided mapping function to each element. Each mapped stream is + * {@link java.util.stream.BaseStream#close() closed} after its contents + * have been placed into this stream. (If a mapped stream is {@code null} + * an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. @@ -270,10 +271,11 @@ /** * Returns an {@code IntStream} consisting of the results of replacing each - * element of this stream with the contents of the stream produced by - * applying the provided mapping function to each element. (If the result - * of the mapping function is {@code null}, this is treated as if the result - * was an empty stream.) + * element of this stream with the contents of a mapped stream produced by + * applying the provided mapping function to each element. Each mapped + * stream is {@link java.util.stream.BaseStream#close() closed} after its + * contents have been placed into this stream. (If a mapped stream is + * {@code null} an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. @@ -288,11 +290,12 @@ IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper); /** - * Returns a {@code LongStream} consisting of the results of replacing each - * element of this stream with the contents of the stream produced - * by applying the provided mapping function to each element. (If the result - * of the mapping function is {@code null}, this is treated as if the result - * was an empty stream.) + * Returns an {@code LongStream} consisting of the results of replacing each + * element of this stream with the contents of a mapped stream produced by + * applying the provided mapping function to each element. Each mapped + * stream is {@link java.util.stream.BaseStream#close() closed} after its + * contents have been placed into this stream. (If a mapped stream is + * {@code null} an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. @@ -307,11 +310,12 @@ LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper); /** - * Returns a {@code DoubleStream} consisting of the results of replacing each - * element of this stream with the contents of the stream produced - * by applying the provided mapping function to each element. (If the result - * of the mapping function is {@code null}, this is treated as if the result - * was an empty stream.) + * Returns an {@code DoubleStream} consisting of the results of replacing + * each element of this stream with the contents of a mapped stream produced + * by applying the provided mapping function to each element. Each mapped + * stream is {@link java.util.stream.BaseStream#close() closed} after its + * contents have placed been into this stream. (If a mapped stream is + * {@code null} an empty stream is used, instead.) * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>.
--- a/src/share/classes/sun/invoke/util/VerifyAccess.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/sun/invoke/util/VerifyAccess.java Thu Feb 06 13:28:20 2014 -0800 @@ -90,35 +90,28 @@ if (allowedModes == 0) return false; assert((allowedModes & PUBLIC) != 0 && (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0); - // Usually refc and defc are the same, but if they differ, verify them both. - if (refc != defc) { - if (!isClassAccessible(refc, lookupClass, allowedModes)) { - // Note that defc is verified in the switch below. - return false; - } - if ((mods & (ALL_ACCESS_MODES|STATIC)) == (PROTECTED|STATIC) && - (allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0) { - // Apply the special rules for refc here. - if (!isRelatedClass(refc, lookupClass)) - return isSamePackage(defc, lookupClass); - // If refc == defc, the call to isPublicSuperClass will do - // the whole job, since in that case refc (as defc) will be - // a superclass of the lookup class. - } + // The symbolic reference class (refc) must always be fully verified. + if (!isClassAccessible(refc, lookupClass, allowedModes)) { + return false; } + // Usually refc and defc are the same, but verify defc also in case they differ. if (defc == lookupClass && (allowedModes & PRIVATE) != 0) return true; // easy check; all self-access is OK switch (mods & ALL_ACCESS_MODES) { case PUBLIC: - if (refc != defc) return true; // already checked above - return isClassAccessible(refc, lookupClass, allowedModes); + return true; // already checked above case PROTECTED: if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)) return true; + if ((allowedModes & PROTECTED) == 0) + return false; + if ((mods & STATIC) != 0 && + !isRelatedClass(refc, lookupClass)) + return false; if ((allowedModes & PROTECTED) != 0 && - isPublicSuperClass(defc, lookupClass)) + isSuperClass(defc, lookupClass)) return true; return false; case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. @@ -140,8 +133,8 @@ lookupClass.isAssignableFrom(refc)); } - static boolean isPublicSuperClass(Class<?> defc, Class<?> lookupClass) { - return isPublic(getClassModifiers(defc)) && defc.isAssignableFrom(lookupClass); + static boolean isSuperClass(Class<?> defc, Class<?> lookupClass) { + return defc.isAssignableFrom(lookupClass); } static int getClassModifiers(Class<?> c) {
--- a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Jan 22 16:15:39 2014 +0400 +++ b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Thu Feb 06 13:28:20 2014 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, 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 @@ -446,10 +446,28 @@ } } else if (responderKeyId != null) { for (X509CertImpl cert : certs) { + // Match responder's key identifier against the cert's SKID + // This will match if the SKID is encoded using the 160-bit + // SHA-1 hash method as defined in RFC 5280. KeyIdentifier certKeyId = cert.getSubjectKeyId(); if (certKeyId != null && responderKeyId.equals(certKeyId)) { signerCert = cert; break; + } else { + // The certificate does not have a SKID or may have + // been using a different algorithm (ex: see RFC 7093). + // Check if the responder's key identifier matches + // against a newly generated key identifier of the + // cert's public key using the 160-bit SHA-1 method. + try { + certKeyId = new KeyIdentifier(cert.getPublicKey()); + } catch (IOException e) { + // ignore + } + if (responderKeyId.equals(certKeyId)) { + signerCert = cert; + break; + } } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Device.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,66 @@ +package checker; + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ + + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Collections; +import java.util.EnumMap; +import java.util.Map; + +/** + * Represents the device configuration. The values are loaded from an XML file by JAXB. + */ +@XmlRootElement +public class Device { + + @XmlElement() + private Map<Module, Integer> supportedModules = new EnumMap<>(Module.class); + + /** + * Returns map of supported modules. The map key is module. The map value is version. + * + * @return map of supported modules. + */ + public Map<Module, Integer> getSupportedModules() { + return Collections.unmodifiableMap(supportedModules); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Kettle.xml Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of Oracle nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + + This source code is provided to illustrate the usage of a given feature + or technique and has been deliberately simplified. Additional steps + required for a production-quality application, such as security checks, + input validation and proper error handling, might not be present in + this sample code. + + --> + +<device> + <supportedModules> + <entry> + <key>DISPLAY</key> + <value>2</value> + </entry> + <entry> + <key>THERMOMETER</key> + <value>1</value> + </entry> + <entry> + <key>CLOCK</key> + <value>4</value> + </entry> + </supportedModules> +</device> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Module.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,49 @@ +package checker; + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ + + +/** + * Represents available modules. + */ +public enum Module { + + DISPLAY, CLOCK, THERMOMETER, HEATER, SPEAKER, GSM, LED; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/PluginChecker.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package checker; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.xml.bind.JAXBContext; +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import javax.xml.bind.JAXBException; + +/** + * Reads the device configuration from the XML file specified by -Adevice=device.xml. + * For each class in a project, checks required modules. If the device doesn't have + * the required module, then a compilation error will be shown. + */ +@SupportedAnnotationTypes("checker.RequireContainer") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class PluginChecker extends javax.annotation.processing.AbstractProcessor { + + /** + * Name of the option to get the path to the xml with device configuration. + */ + public static final String DEVICE_OPTION = "device"; + private Device device; + + /** + * Only the device option is supported. + * + * {@inheritDoc} + */ + @Override + public Set<String> getSupportedOptions() { + return new HashSet<>(Arrays.asList(DEVICE_OPTION)); + } + + /** + * Initializes the processor by loading the device configuration. + * + * {@inheritDoc} + */ + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + try { + String deviceOption = processingEnv.getOptions().get(DEVICE_OPTION); + device = (Device) JAXBContext.newInstance(Device.class) + .createUnmarshaller().unmarshal(new File(deviceOption)); + } catch (JAXBException e) { + throw new RuntimeException( + "Please specify device by -Adevice=device.xml\n" + + e.toString(), e); + } + } + + /** + * Processes @Require annotations and checks that Device meets requirements. + * + * {@inheritDoc} + */ + @Override + public boolean process(Set<? extends TypeElement> annotations, + RoundEnvironment roundEnv) { + for (Element el : roundEnv.getElementsAnnotatedWith(RequireContainer.class)) { + for (Require req : el.getAnnotationsByType(Require.class)) { + //for every Require annotation checks if device has module of required version. + Integer version = device.getSupportedModules().get(req.value()); + + if (version == null + || version < req.minVersion() + || version > req.maxVersion()) { + //if module is optional then show only warning not error + if (req.optional()) { + processingEnv.getMessager() + .printMessage(Diagnostic.Kind.WARNING, + "Plugin [" + el + "] requires " + req + + "\n but device " + (version == null + ? "doesn't have such module." + + " This module is optional." + + " So plugin will work but miss" + + " some functionality" + : "has " + version + + " version of that module")); + } else { + processingEnv.getMessager() + .printMessage(Diagnostic.Kind.ERROR, + "Plugin [" + el + "] requires " + req + + "\n but device " + + (version == null + ? "doesn't have such module" + : "has " + version + + " version of that module")); + } + } + } + return true; + } + return false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Require.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package checker; + +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Indicates that a plug-in depends on a module. + */ +@Retention(RetentionPolicy.CLASS) +@Repeatable(RequireContainer.class) +public @interface Require { + + /** + * Returns the required module. + * + * @return required module. + */ + Module value(); + + /** + * Returns the minimum supported version of a module. + * + * @return minimum supported version of a module. + */ + int minVersion() default 1; + + /** + * Returns the maximum supported version of a module. + * + * @return maximum supported version of a module. + */ + int maxVersion() default Integer.MAX_VALUE; + + /** + * Returns true if a module is optional. A module is optional if a system + * works without that module but is missing some functionality. Returns false if a system + * won't work without the specified module. + * + * @return true if module is optional. False otherwise. + */ + boolean optional() default false; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/RequireContainer.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,51 @@ +package checker; + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A container for the repeatable @Require annotation. + */ +@Retention(RetentionPolicy.CLASS) +public @interface RequireContainer { + + Require[] value(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/BoilerPlugin.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 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 + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package plugins; + +import checker.Module; +import checker.Require; + +/** + * BoilerPlugin provides support for boiling water and keeping water warm. + */ +@Require(value = Module.CLOCK, maxVersion = 3) +@Require(value = Module.THERMOMETER) +@Require(value = Module.HEATER) +@Require(value = Module.LED, optional = true) //will use if present +public class BoilerPlugin { + + /** + * Heats water up to 100 degrees Celsius. + */ + public void boil() { + boil(100); + } + + /** + * Heats water up to temperature. + * + * @param temperature - desired temperature of the water in the boiler + */ + public void boil(int temperature) { + /* + * Turn on heater and wait while temperature reaches desired temperature + * in Celsius. Finally, turn off heater. + * If present, the LED light changes color according to the temperature. + */ + } + + /** + * Keeps desired temperature. + * + * @param temperature - desired temperature of the water in the boiler + * @param seconds - period of time for checking temperature in seconds + */ + public void keepWarm(int temperature, int seconds) { + //Every n seconds check temperature and warm up, if necessary. + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/ExtendedBoilerPlugin.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 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 + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package plugins; + +import checker.Module; +import checker.Require; +import java.util.Calendar; + +/** + * Introduces new features for BoilerPlugin. Features are boiling water by an + * SMS and boiling water by date with notification by a phone call. + */ +@Require(value = Module.SPEAKER) +@Require(value = Module.GSM, minVersion = 3) +@Require(value = Module.DISPLAY) +public class ExtendedBoilerPlugin extends BoilerPlugin { + + /** + * Boils water at the appointed time and wakes you up by a ring and phone + * call. Shows "Good morning" and a quote of the day from the Internet on the + * display. + * + * @param calendar - date and time when water should be boiled + * @param phoneNumber - phone number to call + */ + public void boilAndWakeUp(Calendar calendar, int phoneNumber) { + //implementation + } + + /** + * Boils water at the appointed time by getting an SMS of fixed format. + * Sends an SMS on finish. + * + * @param sms - text of SMS + */ + public void boilBySMS(String sms) { + //implementation + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/TimerPlugin.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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 + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package plugins; + +import checker.Module; +import checker.Require; + +/** + * Timer plug-in is used to support an alarm and a timer. It depends on Display and + * Clock modules. + */ +@Require(Module.DISPLAY) +@Require(value = Module.CLOCK, maxVersion = 3) +public class TimerPlugin { + + /** + * Sets timer. + * + * @param time - the remaining time. + */ + public void timer(long time) { + //start timer + //show the remaining time on display + } + + /** + * Sets alarm. + * + * @param time - the alarm time. + */ + public void alarm(long time) { + //start alarm + //show current time and alarm time on display + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/PositiveIntegerSupplier.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +import java.util.function.Supplier; + +/** + * Supplies a positive number. + */ +@Validate(value = Validator.INTEGER_NUMBER, + description = "It's not an Integer ") +@Validate(value = Validator.POSITIVE_NUMBER, + description = "It's not a positive Number") +public class PositiveIntegerSupplier implements Supplier<String> { + + /** + * Returns a string representation of a positive integer. + * + * @return string representation of a positive integer. + */ + @Override + public String get() { + return "20005"; //random number + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/SupplierValidator.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +import javax.xml.bind.ValidationException; +import java.util.function.Supplier; + +/** + * Validates the supplier. + */ +public class SupplierValidator { + + /** + * Validates the supplier. + * + * @param supplier - Supplier that needs to be validated. + * @return true if supplier has passed validation check. False otherwise. + */ + public static boolean validate(Supplier<?> supplier) { + for (Validate annotation + : supplier.getClass().getAnnotationsByType(Validate.class)) { + try { + annotation.value().validate(supplier); + } catch (ValidationException e) { + System.out.println(annotation.description()); + e.printStackTrace(); + return false; + } + } + return true; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/Validate.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Indicates that the class should be validated by the specified validator. + */ +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(ValidateContainer.class) +public @interface Validate { + + /** + * Returns the validator that should validate the annotated class. + * + * @return Validator that should validate annotated class. + */ + Validator value(); + + /** + * Returns text to describe the failure of the validation check. + * + * @return text to describe the failure of the validation check. + */ + String description() default ""; +} + +/** + * A container for the repeatable @Validate annotation. + * + * @author Andrey Nazarov + */ +@Retention(RetentionPolicy.RUNTIME) +@interface ValidateContainer { + + Validate[] value(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/Validator.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +import javax.xml.bind.ValidationException; +import java.util.function.Supplier; + +/** + * Enum of Validator implementations. + */ +public enum Validator { + + /** + * This validator checks that the string represents an integer. + */ + INTEGER_NUMBER { + /** + * Checks that the string represents an integer. + * + * @param string - a string supplier + * @throws ValidationException if the validation check fails + */ + @Override + void validate(Supplier<?> string) throws ValidationException { + try { + Integer.parseInt((String) string.get()); + } catch (NumberFormatException ex) { + throw new ValidationException("Error while validating " + + string.get()); + } + } + }, + /** + * This validator checks that the string represents a positive number. + */ + POSITIVE_NUMBER { + /** + * Checks that the string represents a positive number. + * + * @param string - an string supplier + * @throws ValidationException if the validation check fails + */ + @Override + void validate(Supplier<?> string) throws ValidationException { + try { + if (Double.compare(0.0, Double.parseDouble( + (String) string.get())) > 0) { + throw new Exception(); + } + } catch (Exception ex) { + throw new ValidationException("Error while validating " + + string.get()); + } + } + }; + + /** + * Checks that the supplier is valid. + * + * @param string - a string supplier + * @throws ValidationException if validation check fails + */ + abstract void validate(Supplier<?> string) throws ValidationException; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/index.html Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html> +<head> + <title>Repeating Annotations Demo</title> +</head> +<body> +<h2>Repeating Annotations Demo</h2> + +<p> + This demo shows how to use repeating annotations at runtime and at compile time. +</p> + +<ul> + <li><h3>Dependency checker.</h3> + + <p> + Shows how to define repeating annotations and process them at compile time. + The problem domain is some code that performs useful operations on hardware devices. + The code relies on "modules" to be present on the devices. Applicability of the code to a particular + device is checked while compiling the code for a particular device. + A set of modules provided by a device is listed in an xml file that turns red during the compilation + phase and is compared with the required module set specified by annotations. + For instance, there is kettle with hardware modules: thermometer, display, and clock. + There is also a boiler plug-in that requires clock, thermometer, heater, and optionally an LED light. + + Build the PluginChecker annotation processor first. + Then, run javac with the annotation processor against plug-in sources using the following command: </p> + + <code>javac -cp "PluginChecker.jar" -processor checker.PluginChecker -Adevice=Kettle.xml -proc:only <source + files></code> + + <p> + where <code>PluginChecker.jar</code> - path to jar file that contains PluginChecker annotation processor + class. </br> + <code>Kettle.xml</code> - path to device descriptor Kettle.xml </br> + <code><source files></code> - source files in Plugins/src + </p> + For more information, see the source files. + </p> + <ul> + <li>Annotation processor sources: <a href="DependencyChecker/PluginChecker/src/">DependencyChecker/PluginChecker/src</a> + <li>Processing of repeating annotations can be found in <a href="DependencyChecker/PluginChecker/src/checker/PluginChecker.java">PluginChecker.java</a> + <li>Usage of repeating annotation is shown in modules sources.<a href="DependencyChecker/Plugins/src">DependencyChecker/Plugins/src</a> + </ul> + + <li><h3>Validator.</h3> + + <p> + Shows how to define repeating annotations and process them at runtime. + A problem domain is code that needs to validate provided Suppliers for conformance to some criteria. + The criteria are implemented by the Validator class which is applied by using annotations that are placed in + the code whenever validation is needed. For more information, see the + source files. + </p> + + <p> + <ul> + <li>Usage of repeating annotation is described in <a href="Validator/src/PositiveIntegerSupplier.java">PositiveIntegerSupplier.java</a> + <li> Example of how to define a repeating annotation type can be found in + <a href="Validator/src/Validate.java">Validate.java</a> + <li> Usages of the new reflective methods can be found in <a href="Validator/src/SupplierValidator.java">SupplierValidator.java</a> + </ul> + </p> + Sources: <a href="Validator/src/">Validator/src/</a> +</ul> +</body> +</html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/index.html Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html> +<head> + <title>Bulk Data Operations Demo</title> +</head> +<body> +<h2>Bulk Data Operations Demo</h2> + +<p> + This demo shows how to use bulk data operations with the new JDK8 + Collections API. + The demo also demonstrates new features of JDK8 such as lambda expressions + and method/constructor references. +</p> + +<ul> + <li><h3>CSV Processor</h3> + + <p> + Analyzes a CSV file, finds and collects useful information, computes + different statistics. For more information, see the source file. + </p> + Source: <a href="src/CSVProcessor.java">src/CSVProcessor.java</a> + <li><h3>Grep</h3> + + <p> + Behaves like the standard Linux tool Grep. For more information, see + the source file. + </p> + Source: <a href="src/Grep.java">src/Grep.java</a> + <li><h3>PasswordGenerator</h3> + + <p> + Produces a password of desired length. For more information see + source file. + </p> + Source: <a + href="src/PasswordGenerator.java">src/PasswordGenerator.java</a> + <li><h3>WC</h3> + + <p> + Counts newlines, words, characters, and the maximum line length of a + text file. For more information, see the source + file. + </p> + Source: <a href="src/WC.java">src/WC.java</a> +</ul> +</body> +</html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/CSVProcessor.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.function.*; +import java.util.regex.Pattern; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +import static java.lang.Double.parseDouble; +import static java.util.stream.Collectors.*; + +/** + * CSVProcessor is a tool for processing CSV files. There are several + * command-line options. Consult the {@link #printUsageAndExit} method for + * instructions and command line parameters. This sample shows examples of the + * following features: + * <ul> + * <li>Lambda and bulk operations. Working with streams: map(...), filter(...), + * sorted(...) methods. The collect(...) method with different collectors: + * Collectors.maxBy(...), Collectors.minBy(...), Collectors.toList(), + * Collectors.toCollection(...), Collectors.groupingBy(...), + * Collectors.toDoubleSummaryStatistics(...), and a custom Collector.</li> + * <li>Static method reference for printing values.</li> + * <li>Try-with-resources feature for closing files.</li> + * <li>Switch by String feature.</li> + * <li>Other new APIs: Pattern.asPredicate(), BinaryOperator + * BufferedReader.lines(), Collection.forEach(...), Comparator.comparing(...), + * Comparator.reversed(), Arrays.stream(...).</li> + * </ul> + * + */ +public class CSVProcessor { + + //Number of characters that may be read + private static final int READ_AHEAD_LIMIT = 100_000_000; + + /** + * The main method for the CSVProcessor program. Run the program with an + * empty argument list to see possible arguments. + * + * @param args the argument list for CSVProcessor. + */ + public static void main(String[] args) { + if (args.length < 2) { + printUsageAndExit(); + } + try (BufferedReader br = new BufferedReader( + Files.newBufferedReader(Paths.get(args[args.length - 1])))) { + //Assume that the first line contains column names. + List<String> header = Arrays.stream(br.readLine().split(",")) + .map(String::trim).collect(toList()); + //Calculate an index of the column in question. + int column = getColumnNumber(header, args[1]); + switch (args[0]) { + case "sort": + verifyArgumentNumber(args, 4); + //Define the sort order. + boolean isAsc; + switch (args[2].toUpperCase()) { + case "ASC": + isAsc = true; + break; + case "DESC": + isAsc = false; + break; + default: + printUsageAndExit("Illegal argument" + args[2]); + return;//Should not be reached. + } + /* + * Create a comparator that compares lines by comparing + * values in the specified column. + */ + Comparator<String> cmp + = Comparator.comparing(str -> getCell(str, column), + String.CASE_INSENSITIVE_ORDER); + /* + * sorted(...) is used to sort records. + * forEach(...) is used to output sorted records. + */ + br.lines().sorted(isAsc ? cmp : cmp.reversed()) + .forEach(System.out::println); + break; + case "search": + verifyArgumentNumber(args, 4); + /* + * Records are filtered by a regex. + * forEach(...) is used to output filtered records. + */ + Predicate<String> pattern + = Pattern.compile(args[2]).asPredicate(); + br.lines().filter(str -> pattern.test(getCell(str, column))) + .forEach(System.out::println); + break; + case "groupby": + verifyArgumentNumber(args, 3); + /* + * Group lines by values in the column with collect(...), and + * print with forEach(...) for every distinct value within + * the column. + */ + br.lines().collect( + Collectors.groupingBy(str -> getCell(str, column), + toCollection(TreeSet::new))) + .forEach((str, set) -> { + System.out.println(str + ":"); + set.forEach(System.out::println); + }); + break; + case "stat": + verifyArgumentNumber(args, 3); + + /* + * BufferedReader will be read several times. + * Mark this point to return here after each pass. + * BufferedReader will be read right after the headers line + * because it is already read. + */ + br.mark(READ_AHEAD_LIMIT); + + /* + * Statistics can be collected by a custom collector in one + * pass. One pass is preferable. + */ + System.out.println( + br.lines().collect(new Statistics(column))); + + /* + * Alternatively, statistics can be collected + * by a built-in API in several passes. + * This method demonstrates how separate operations can be + * implemented using a built-in API. + */ + br.reset(); + statInSeveralPasses(br, column); + break; + default: + printUsageAndExit("Illegal argument" + args[0]); + } + } catch (IOException e) { + printUsageAndExit(e.toString()); + } + } + + private static void statInSeveralPasses(BufferedReader br, int column) + throws IOException { + System.out.println("#-----Statistics in several passes-------#"); + //Create a comparator to compare records by the column. + Comparator<String> comparator + = Comparator.comparing( + (String str) -> parseDouble(getCell(str, column))); + //Find max record by using Collectors.maxBy(...) + System.out.println( + "Max: " + br.lines().collect(maxBy(comparator)).get()); + br.reset(); + //Find min record by using Collectors.minBy(...) + System.out.println( + "Min: " + br.lines().collect(minBy(comparator)).get()); + br.reset(); + //Compute the average value and sum with + //Collectors.toDoubleSummaryStatistics(...) + DoubleSummaryStatistics doubleSummaryStatistics + = br.lines().collect(summarizingDouble( + str -> parseDouble(getCell(str, column)))); + System.out.println("Average: " + doubleSummaryStatistics.getAverage()); + System.out.println("Sum: " + doubleSummaryStatistics.getSum()); + } + + private static void verifyArgumentNumber(String[] args, int n) { + if (args.length != n) { + printUsageAndExit("Expected " + n + " arguments but was " + + args.length); + } + } + + private static int getColumnNumber(List<String> header, String name) { + int column = header.indexOf(name); + if (column == -1) { + printUsageAndExit("There is no column with name " + name); + } + return column; + } + + private static String getCell(String record, int column) { + return record.split(",")[column].trim(); + } + + private static void printUsageAndExit(String... str) { + System.out.println("Usages:"); + + System.out.println("CSVProcessor sort COLUMN_NAME ASC|DESC FILE"); + System.out.println("Sort lines by column COLUMN_NAME in CSV FILE\n"); + + System.out.println("CSVProcessor search COLUMN_NAME REGEX FILE"); + System.out.println("Search for REGEX in column COLUMN_NAME in CSV FILE\n"); + + System.out.println("CSVProcessor groupby COLUMN_NAME FILE"); + System.out.println("Split lines into different groups according to column " + + "COLUMN_NAME value\n"); + + System.out.println("CSVProcessor stat COLUMN_NAME FILE"); + System.out.println("Compute max/min/average/sum statistics by column " + + "COLUMN_NAME\n"); + + Arrays.asList(str).forEach(System.err::println); + System.exit(1); + } + + /* + * This is a custom implementation of the Collector interface. + * Statistics are objects gather max,min,sum,average statistics. + */ + private static class Statistics + implements Collector<String, Statistics, Statistics> { + + + /* + * This implementation does not need to be thread safe because + * the parallel implementation of + * {@link java.util.stream.Stream#collect Stream.collect()} + * provides the necessary partitioning and isolation for safe parallel + * execution. + */ + private String maxRecord; + private String minRecord; + + private double sum; + private int lineCount; + private final BinaryOperator<String> maxOperator; + private final BinaryOperator<String> minOperator; + private final int column; + + public Statistics(int column) { + this.column = column; + Comparator<String> cmp = Comparator.comparing( + (String str) -> parseDouble(getCell(str, column))); + maxOperator = BinaryOperator.maxBy(cmp); + minOperator = BinaryOperator.minBy(cmp); + } + + /* + * Process line. + */ + public Statistics accept(String line) { + maxRecord = maxRecord == null + ? line : maxOperator.apply(maxRecord, line); + minRecord = minRecord == null + ? line : minOperator.apply(minRecord, line); + + sum += parseDouble(getCell(line, column)); + lineCount++; + return this; + } + + + /* + * Merge two Statistics. + */ + public Statistics combine(Statistics stat) { + maxRecord = maxOperator.apply(maxRecord, stat.getMaxRecord()); + minRecord = minOperator.apply(minRecord, stat.getMinRecord()); + sum += stat.getSum(); + lineCount += stat.getLineCount(); + return this; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("#------Statistics------#\n"); + sb.append("Max: ").append(getMaxRecord()).append("\n"); + sb.append("Min: ").append(getMinRecord()).append("\n"); + sb.append("Sum = ").append(getSum()).append("\n"); + sb.append("Average = ").append(average()).append("\n"); + sb.append("#------Statistics------#\n"); + return sb.toString(); + } + + @Override + public Supplier<Statistics> supplier() { + return () -> new Statistics(column); + } + + @Override + public BiConsumer<Statistics, String> accumulator() { + return Statistics::accept; + } + + @Override + public BinaryOperator<Statistics> combiner() { + return Statistics::combine; + + } + + @Override + public Function<Statistics, Statistics> finisher() { + return stat -> stat; + } + + @Override + public Set<Characteristics> characteristics() { + return EnumSet.of(Characteristics.IDENTITY_FINISH); + } + + private String getMaxRecord() { + return maxRecord; + } + + private String getMinRecord() { + return minRecord; + } + + private double getSum() { + return sum; + } + + private double average() { + return sum / lineCount; + } + + private int getLineCount() { + return lineCount; + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/Grep.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; + +/** + * Grep prints lines matching a regex. See {@link #printUsageAndExit(String...)} + * method for instructions and command line parameters. This sample shows + * examples of using next features: + * <ul> + * <li>Lambda and bulk operations. Working with streams: + * map(...),filter(...),flatMap(...),limit(...) methods.</li> + * <li>Static method reference for printing values.</li> + * <li>New Collections API forEach(...) method.</li> + * <li>Try-with-resources feature.</li> + * <li>new Files.walk(...), Files.lines(...) API.</li> + * <li>Streams that need to be closed.</li> + * </ul> + * + */ +public class Grep { + + private static void printUsageAndExit(String... str) { + System.out.println("Usage: " + Grep.class.getSimpleName() + + " [OPTION]... PATTERN FILE..."); + System.out.println("Search for PATTERN in each FILE. " + + "If FILE is a directory then whole file tree of the directory" + + " will be processed."); + System.out.println("Example: grep -m 100 'hello world' menu.h main.c"); + System.out.println("Options:"); + System.out.println(" -m NUM: stop analysis after NUM matches"); + Arrays.asList(str).forEach(System.err::println); + System.exit(1); + } + + /** + * The main method for the Grep program. Run program with empty argument + * list to see possible arguments. + * + * @param args the argument list for Grep. + * @throws java.io.IOException If an I/O error occurs. + */ + public static void main(String[] args) throws IOException { + long maxCount = Long.MAX_VALUE; + if (args.length < 2) { + printUsageAndExit(); + } + int i = 0; + //parse OPTIONS + while (args[i].startsWith("-")) { + switch (args[i]) { + case "-m": + try { + maxCount = Long.parseLong(args[++i]); + } catch (NumberFormatException ex) { + printUsageAndExit(ex.toString()); + } + break; + default: + printUsageAndExit("Unexpected option " + args[i]); + } + i++; + } + //parse PATTERN + Pattern pattern = Pattern.compile(args[i++]); + if (i == args.length) { + printUsageAndExit("There are no files for input"); + } + + try { + /* + * First obtain the list of all paths. + * For a small number of arguments there is little to be gained + * by producing this list in parallel. For one argument + * there will be no parallelism. + * + * File names are converted to paths. If a path is a directory then + * Stream is populated with whole file tree of the directory by + * flatMap() method. Files are filtered from directories. + */ + List<Path> files = Arrays.stream(args, i, args.length) + .map(Paths::get) + // flatMap will ensure each I/O-based stream will be closed + .flatMap(Grep::getPathStream) + .filter(Files::isRegularFile) + .collect(toList()); + /* + * Then operate on that list in parallel. + * This is likely to give a more even distribution of work for + * parallel execution. + * + * Lines are extracted from files. Lines are filtered by pattern. + * Stream is limited by number of matches. Each remaining string is + * displayed in std output by method reference System.out::println. + */ + files.parallelStream() + // flatMap will ensure each I/O-based stream will be closed + .flatMap(Grep::path2Lines) + .filter(pattern.asPredicate()) + .limit(maxCount) + .forEachOrdered(System.out::println); + } catch (UncheckedIOException ioe) { + printUsageAndExit(ioe.toString()); + } + } + + /** + * Flattens file system hierarchy into a stream. This code is not inlined + * for the reason of Files.walk() throwing a checked IOException that must + * be caught. + * + * @param path - the file or directory + * @return Whole file tree starting from path, a stream with one element - + * the path itself - if it is a file. + */ + private static Stream<Path> getPathStream(Path path) { + try { + return Files.walk(path); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Produces a stream of lines from a file. The result is a stream in order + * to close it later. This code is not inlined for the reason of + * Files.lines() throwing a checked IOException that must be caught. + * + * @param path - the file to read + * @return stream of lines from the file + */ + private static Stream<String> path2Lines(Path path) { + try { + return Files.lines(path); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/PasswordGenerator.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +/** + * Generates password of desired length. See {@link #usage} method + * for instructions and command line parameters. This sample shows usages of: + * <ul> + * <li>Method references.</li> + * <li>Lambda and bulk operations. A stream of random integers is mapped to + * chars, limited by desired length and printed in standard output as password + * string.</li> + * </ul> + * + */ +public class PasswordGenerator { + + private static void usage() { + System.out.println("Usage: PasswordGenerator LENGTH"); + System.out.println( + "Password Generator produces password of desired LENGTH."); + } + + private static final List<Integer> PASSWORD_CHARS = new ArrayList<>(); + + //Valid symbols. + static { + IntStream.rangeClosed('0', '9').forEach(PASSWORD_CHARS::add); // 0-9 + IntStream.rangeClosed('A', 'Z').forEach(PASSWORD_CHARS::add); // A-Z + IntStream.rangeClosed('a', 'z').forEach(PASSWORD_CHARS::add); // a-z + } + + /** + * The main method for the PasswordGenerator program. Run program with empty + * argument list to see possible arguments. + * + * @param args the argument list for PasswordGenerator. + */ + public static void main(String[] args) { + + if (args.length != 1) { + usage(); + return; + } + + long passwordLength; + try { + passwordLength = Long.parseLong(args[0]); + if (passwordLength < 1) { + printMessageAndUsage("Length has to be positive"); + return; + } + } catch (NumberFormatException ex) { + printMessageAndUsage("Unexpected number format" + args[0]); + return; + } + /* + * Stream of random integers is created containing Integer values + * in range from 0 to PASSWORD_CHARS.size(). + * The stream is limited by passwordLength. + * Valid chars are selected by generated index. + */ + new SecureRandom().ints(passwordLength, 0, PASSWORD_CHARS.size()) + .map(PASSWORD_CHARS::get) + .forEach(i -> System.out.print((char) i)); + } + + private static void printMessageAndUsage(String message) { + System.err.println(message); + usage(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/WC.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.function.Consumer; +import java.util.regex.Pattern; + +/** + * WC - Prints newline, word, and character counts for each file. See + * the {@link #usage} method for instructions and command line parameters. This + * sample shows usages of: + * <ul> + * <li>Lambda and bulk operations. Shows how to create a custom collector to + * gather custom statistics. Implements the collection of statistics using a + * built-in API.</li> + * <li>Constructor reference.</li> + * <li>Try-with-resources feature.</li> + * </ul> + * + */ +public class WC { + + //The number of characters that may be read. + private static final int READ_AHEAD_LIMIT = 100_000_000; + + //The pattern for splitting strings by non word characters to get words. + private static final Pattern nonWordPattern = Pattern.compile("\\W"); + + /** + * The main method for the WC program. Run the program with an empty + * argument list to see possible arguments. + * + * @param args the argument list for WC + * @throws java.io.IOException If an input exception occurred. + */ + public static void main(String[] args) throws IOException { + + if (args.length != 1) { + usage(); + return; + } + + try (BufferedReader reader = new BufferedReader( + new FileReader(args[0]))) { + reader.mark(READ_AHEAD_LIMIT); + /* + * Statistics can be gathered in four passes using a built-in API. + * The method demonstrates how separate operations can be + * implemented using a built-in API. + */ + collectInFourPasses(reader); + /* + * Usage of several passes to collect data is not the best way. + * Statistics can be gathered by a custom collector in one pass. + */ + reader.reset(); + collectInOnePass(reader); + } catch (FileNotFoundException e) { + usage(); + System.err.println(e); + } + } + + private static void collectInFourPasses(BufferedReader reader) + throws IOException { + /* + * Input is read as a stream of lines by lines(). + * Every line is turned into a stream of chars by the flatMapToInt(...) + * method. + * Length of the stream is counted by count(). + */ + System.out.println("Character count = " + + reader.lines().flatMapToInt(String::chars).count()); + /* + * Input is read as a stream of lines by lines(). + * Every line is split by nonWordPattern into words by flatMap(...) + * method. + * Empty lines are removed by the filter(...) method. + * Length of the stream is counted by count(). + */ + reader.reset(); + System.out.println("Word count = " + + reader.lines() + .flatMap(nonWordPattern::splitAsStream) + .filter(str -> !str.isEmpty()).count()); + + reader.reset(); + System.out.println("Newline count = " + reader.lines().count()); + /* + * Input is read as a stream of lines by lines(). + * Every line is mapped to its length. + * Maximum of the lengths is calculated. + */ + reader.reset(); + System.out.println("Max line length = " + + reader.lines().mapToInt(String::length).max().getAsInt()); + } + + private static void collectInOnePass(BufferedReader reader) { + /* + * The collect() method has three parameters: + * The first parameter is the {@code WCStatistic} constructor reference. + * collect() will create {@code WCStatistics} instances, where + * statistics will be aggregated. + * The second parameter shows how {@code WCStatistics} will process + * String. + * The third parameter shows how to merge two {@code WCStatistic} + * instances. + * + * Also {@code Collector} can be used, which would be more reusable + * solution. See {@code CSVProcessor} example for how {@code Collector} + * can be implemented. + * + * Note that the any performance increase when going parallel will + * depend on the size of the input (lines) and the cost per-element. + */ + WCStatistics wc = reader.lines().parallel() + .collect(WCStatistics::new, + WCStatistics::accept, + WCStatistics::combine); + System.out.println(wc); + } + + private static void usage() { + System.out.println("Usage: " + WC.class.getSimpleName() + " FILE"); + System.out.println("Print newline, word," + + " character counts and max line length for FILE."); + } + + private static class WCStatistics implements Consumer<String> { + /* + * @implNote This implementation does not need to be thread safe because + * the parallel implementation of + * {@link java.util.stream.Stream#collect Stream.collect()} + * provides the necessary partitioning and isolation for safe parallel + * execution. + */ + + private long characterCount; + private long lineCount; + private long wordCount; + private long maxLineLength; + + + /* + * Processes line. + */ + @Override + public void accept(String line) { + characterCount += line.length(); + lineCount++; + wordCount += nonWordPattern.splitAsStream(line) + .filter(str -> !str.isEmpty()).count(); + maxLineLength = Math.max(maxLineLength, line.length()); + } + + /* + * Merges two WCStatistics. + */ + public void combine(WCStatistics stat) { + wordCount += stat.wordCount; + lineCount += stat.lineCount; + characterCount += stat.characterCount; + maxLineLength = Math.max(maxLineLength, stat.maxLineLength); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("#------WCStatistic------#\n"); + sb.append("Character count = ").append(characterCount).append('\n'); + sb.append("Word count = ").append(wordCount).append('\n'); + sb.append("Newline count = ").append(lineCount).append('\n'); + sb.append("Max line length = ").append(maxLineLength).append('\n'); + return sb.toString(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/ArrayIterator.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * The code sample illustrates the usage of default methods in the JDK 8. Most + * implementations of {@link Iterator} don't provide a useful + * {@link Iterator#remove()} method, however, + * they still have to implement this method to throw + * an UnsupportedOperationException. With the default method, the same + * default behavior in interface Iterator itself can be provided. + */ +public class ArrayIterator { + + /** Close the constructor because ArrayIterator is part of the utility + * class. + */ + protected ArrayIterator() { + throw new UnsupportedOperationException(); + } + + /** + * Returns an iterator that goes over the elements in the array. + * + * @param <E> type of an array element + * @param array source array to iterate over it + * @return an iterator that goes over the elements in the array + */ + public static <E> Iterator<E> iterator(final E[] array) { + return new Iterator<E>() { + /** + * Index of the current position + * + */ + private int index = 0; + + /** + * Returns the next element in the iteration + * + * @return the next element in the iteration + * @throws NoSuchElementException if the iteration has no more + * elements + */ + @Override + public boolean hasNext() { + return (index < array.length); + } + + /** + * Returns {@code true} if the iteration has more elements. (In + * other words, returns {@code true} if {@link #next} returns + * an element, rather than throwing an exception.) + * + * @return {@code true} if the iteration has more elements + */ + @Override + public E next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return array[index++]; + } + + /** + * This method does not need to be overwritten in JDK 8. + */ + //@Override + //public void remove() { + // throw UnsupportedOperationException( + // "Arrays don't support remove.") + //} + }; + } + + /** + * Sample usage of the ArrayIterator + * + * @param args command-line arguments + */ + public static void main(final String[] args) { + Iterator<String> it = ArrayIterator.iterator( + new String[]{"one", "two", "three"}); + + while (it.hasNext()) { + System.out.println(it.next()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/DiamondInheritance.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * This sample diamond interface inheritance with <b>default methods</b>. + * If there's not already a unique method implementation to inherit, + * you must provide it. The inheritance diagram is similar to the following: + * <pre> + * Animal + * / \ + * Horse Bird + * \ / + * Pegasus + * </pre> + * + * Both {@link Horse} and {@link Bird} interfaces implements the <code>go</code> + * method. The {@link Pegasus} class have to overrides the + * <code>go</code> method. + * + * The new syntax of super-call is used here: + * <pre> + * <interface_name>.super.<method>(...); + * For example: Horse.super.go(); + * </pre> So, Pegasus moves like a horse. + */ +public class DiamondInheritance { + + /** + * Base interface to illustrate the diamond inheritance. + * + * @see DiamondInheritance + */ + public interface Animal { + + /** + * Return string representation of the "go" action for concrete animal + * + * @return string representation of the "go" action for concrete animal + */ + String go(); + } + + /** + * Interface to illustrate the diamond inheritance. + * + * @see DiamondInheritance + */ + public interface Horse extends Animal { + + /** + * Return string representation of the "go" action for horse + * + * @return string representation of the "go" action for horse + */ + @Override + default String go() { + return this.getClass().getSimpleName() + " walks on four legs"; + } + } + + /** + * Interface to illustrate the diamond inheritance. + * + * @see DiamondInheritance + */ + public interface Bird extends Animal { + + /** + * Return string representation of the "go" action for bird + * + * @return string representation of the "go" action for bird + */ + @Override + default String go() { + return this.getClass().getSimpleName() + " walks on two legs"; + } + + /** + * Return string representation of the "fly" action for bird + * + * @return string representation of the "fly" action for bird + */ + default String fly() { + return "I can fly"; + } + } + + /** + * Class to illustrate the diamond inheritance. Pegasus must mix horse and + * bird behavior. + * + * @see DiamondInheritance + */ + public static class Pegasus implements Horse, Bird { + + /** + * Return string representation of the "go" action for the fictitious + * creature Pegasus + * + * @return string representation of the "go" action for the fictitious + * creature Pegasus + */ + @Override + public String go() { + return Horse.super.go(); + } + } + + /** + * Illustrate the behavior of the {@link Pegasus} class + * + * @param args command line arguments + */ + public static void main(final String[] args) { + System.out.println(new Pegasus().go()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/Inheritance.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The sample illustrates rules to resolve conflicts between inheritance + * candidates with <b>default methods</b>. There are two simple rules: + * <ul> + * <li>Class wins. If the superclass has a concrete or abstract declaration of + * this method, then it is preferred over all defaults.</li> + * <li>Subtype wins. If an interface extends another interface, and both provide + * a default, then the more specific interface wins. </li> + * </ul> + */ +public class Inheritance { + + /** + * The behavior of an creature that can swim + */ + public interface Swimable { + + /** + * Return string representation of the swim action for a creature that + * can swim + * + * @return string representation of the swim action for a creature + * that can swim + */ + default String swim() { + return "I can swim."; + } + } + + /** + * The abstract class that overrides {@link #swim} method + */ + public abstract static class Fish implements Swimable { + + /** + * Return string representation of the swim action for a fish + * + * @return string representation of the swim action for a fish + */ + @Override + public String swim() { + return this.getClass().getSimpleName() + " swims under water"; + } + } + + /** + * This class is used for the illustration rule of 1. See the source code + * of the {@link #main} method. + * <pre> + * System.out.println(new Tuna().swim()); //"Tuna swims under water" output is suspected here + * </pre> + */ + public static class Tuna extends Fish implements Swimable { + } + + /** + * The behavior of an creature that can dive: the interface that overrides + * {@link #swim} method (subtype of {@link Swimable}) + */ + public interface Diveable extends Swimable { + + /** + * Return string representation of the swim action for a creature that + * can dive + * + * @return string representation of the swim action for a creature + * that can dive + */ + @Override + default String swim() { + return "I can swim on the surface of the water."; + } + + /** + * Return string representation of the dive action for a creature that + * can dive + * + * @return string representation of the dive action for a creature + * that can dive + */ + default String dive() { + return "I can dive."; + } + } + + /** + * This class is used for the illustration of rule 2. See the source code + * of the {@link #main} method + * <pre> + * //"I can swim on the surface of the water." output is suspected here + * System.out.println(new Duck().swim()); + * </pre> + */ + public static class Duck implements Swimable, Diveable { + } + + /** + * Illustrate behavior of the classes: {@link Tuna} and {@link Duck} + * + * @param args command line arguments + */ + public static void main(final String[] args) { + // Illustrates rule 1. The Fish.swim() implementation wins + //"Tuna swims under water" is output + System.out.println(new Tuna().swim()); + + // Illustrates rule 2. The Diveable.swim() implementation wins + //"I can swim on the surface of the water." is output + System.out.println(new Duck().swim()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/MixIn.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.IOException; +import java.lang.reflect.Field; + +/** + * The example illustrates how to use the default method for mixin. + * @see BuildType + * @see Debuggable + */ +public class MixIn { + + /** + * Implement this interface for a class that must be in debug print + */ + public interface Debuggable { + + /** + * Print the class name and all fields to a string. Uses reflection to + * obtain and access fields of this object. + * + * @return the string formatted like the following: <pre> + * State of the: <Class Name> + * <member name> : <value> + * ... + * </pre> + */ + default String toDebugString() { + StringBuilder sb = new StringBuilder(); + sb.append("State of the: ").append( + this.getClass().getSimpleName()).append("\n"); + for (Class cls = this.getClass(); + cls != null; + cls = cls.getSuperclass()) { + for (Field f : cls.getDeclaredFields()) { + try { + f.setAccessible(true); + sb.append(f.getName()).append(" : "). + append(f.get(this)).append("\n"); + } catch (IllegalAccessException e) { + } + } + } + return sb.toString(); + } + } + + /** + * Sample exception class to demonstrate mixin. This enum inherits the + * behavior of the {@link Debuggable} + */ + public static enum BuildType implements Debuggable { + + BUILD(0, "-build"), + PLAN(0, "-plan"), + EXCLUDE(1, "-exclude"), + TOTAL(2, "-total"); + + private final int compareOrder; + private final String pathSuffix; + + private BuildType(int compareOrder, String pathSuffix) { + this.compareOrder = compareOrder; + this.pathSuffix = pathSuffix; + } + + public int getCompareOrder() { + return compareOrder; + } + + public String getPathSuffix() { + return pathSuffix; + } + } + + /** + * Illustrate the behavior of the MixClass + * + * @param args command-line arguments + * @throws java.io.IOException internal demo error + */ + public static void main(final String[] args) throws IOException { + System.out.println(BuildType.BUILD.toDebugString()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/Reflection.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.stream.Stream; + +/** + * The code sample illustrates changes in the reflection API linked + * <b>default methods</b>. Since Java SE 8, a new method is added into the class + * <b><code>java.lang.reflect.Method</code></b>, with which you can reflectively + * determine whether or not a default method provided by an interface + * (<b><code>Method.isDefault()</code></b>). + */ +public class Reflection { + + /** + * Base interface to illustrate the new reflection API. + * + * @see Dog + */ + public interface Animal { + + /** + * Return string representation of the eat action for Animal + * + * @return string representation of the eat action for Animal + */ + default String eat() { + return this.getClass().getSimpleName() + + " eats like an ordinary animal"; + } + + /** + * Return string representation of the sleep action for Animal + * + * @return string representation of the sleep action for Animal + */ + default String sleep() { + return this.getClass().getSimpleName() + + " sleeps like an ordinary animal"; + } + + /** + * Return string representation of the go action for Animal + * + * @return string representation of the go action for Animal + */ + String go(); + } + + /** + * Dog class to illustrate the new reflection API. You can see that: + * <ul> + * <li> the {@link #go} and {@link #sleep} methods are not default. + * {@link #go} is not the default implementation and the {@link #sleep} + * method implementation wins as subtype (according with {@link Inheritance} + * rule. 2) </li> + * <li> the {@link #eat} is a simple default method that is not overridden + * in this class. + * </li> + * </ul> + */ + public static class Dog implements Animal { + + /** + * Return string representation of the go action for Dog + * + * @return string representation of the go action for Dog + */ + @Override + public String go() { + return "Dog walks on four legs"; + } + + /** + * Return string representation of the sleep action for Dog + * + * @return string representation of the sleep action for Dog + */ + @Override + public String sleep() { + return "Dog sleeps"; + } + } + + /** + * Illustrate the usage of the method java.lang.reflect.Method.isDefault() + * + * @param args command-line arguments + * @throws NoSuchMethodException internal demo error + */ + public static void main(final String[] args) throws NoSuchMethodException { + Dog dog = new Dog(); + Stream.of(Dog.class.getMethod("eat"), Dog.class.getMethod("go"), Dog.class.getMethod("sleep")) + .forEach((m) -> { + System.out.println("Method name: " + m.getName()); + System.out.println(" isDefault: " + m.isDefault()); + System.out.print(" invoke: "); + try { + m.invoke(dog); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + } + System.out.println(); + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/SimplestUsage.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The sample illustrates the simplest use case of the <b>default methods</b>. + */ +public class SimplestUsage { + + /** + * The Animal interface provides the default implementation + * of the {@link #eat} method. + */ + public interface Animal { + + /** + * Return string representation of the eat action for Animal + * + * @return string representation of the eat action for Animal + */ + default String eat() { + return this.getClass().getSimpleName() + + " eats like an ordinary animal"; + } + } + + /** + * The Dog class doesn't have its own implementation of the {@link #eat} + * method and uses the default implementation. + */ + public static class Dog implements Animal { + } + + /** + * The Mosquito class implements {@link #eat} method, its own implementation + * overrides the default implementation. + * + */ + public static class Mosquito implements Animal { + + /** + * Return string representation of the eat action for Mosquito + * + * @return string representation of the eat action for Mosquito + */ + @Override + public String eat() { + return "Mosquito consumes blood"; + } + } + + /** + * Illustrate behavior of the classes: {@link Dog} and {@link Mosquito} + * + * @param args command-line arguments + */ + public static void main(String[] args) { + // "Dog eats like an ordinary animal" is output + System.out.println(new Dog().eat()); + + // "Mosquito consumes blood" is output + System.out.println(new Mosquito().eat()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/index.html Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,36 @@ +<!DOCTYPE html> + +<html> +<head> + <title>Try-with-Resources Feature Demo</title> +</head> +<body> +<h2>Try-with-Resources Feature Demo</h2> + +<p> + This demo shows how to use the try-with-resources feature introduced in JDK7. +</p> + +<ul> + <li><h3>Custom AutoCloseable.</h3> + + <p> + Shows how to use a custom resource with the try-with-resources construct. + For more information, see the source file. + </p> + Source: <a href="src/CustomAutoCloseableSample.java">src/CustomAutoCloseableSample.java</a> + + <li><h3>Unzip</h3> + + <p> + Extracts archived files. For more information, see the source file. + </p> + Source: <a href="src/Unzip.java">src/Unzip.java</a> + <li><h3>ZipCat</h3> + + <p>Prints data about a specified file from an archive. For more information, see the source file.</p> + Source: <a href="src/ZipCat.java">src/ZipCat.java</a> + +</ul> +</body> +</html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/src/CustomAutoCloseableSample.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * This sample demonstrates the ability to create custom resource that + * implements the {@code AutoCloseable} interface. This resource can be used in + * the try-with-resources construct. + */ +public class CustomAutoCloseableSample { + + /** + * The main method for the CustomAutoCloseableSample program. + * + * @param args is not used. + */ + public static void main(String[] args) { + /* + * TeeStream will be closed automatically after the try block. + */ + try (TeeStream teeStream = new TeeStream(System.out, Paths.get("out.txt")); + PrintStream out = new PrintStream(teeStream)) { + out.print("Hello, world"); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + /** + * Passes the output through to the specified output stream while copying it into a file. + * The TeeStream functionality is similar to the Unix tee utility. + * TeeStream implements AutoCloseable interface. See OutputStream for details. + */ + public static class TeeStream extends OutputStream { + + private final OutputStream fileStream; + private final OutputStream outputStream; + + /** + * Creates a TeeStream. + * + * @param outputStream an output stream. + * @param outputFile an path to file. + * @throws IOException If an I/O error occurs. + */ + public TeeStream(OutputStream outputStream, Path outputFile) throws IOException { + this.fileStream = new BufferedOutputStream(Files.newOutputStream(outputFile)); + this.outputStream = outputStream; + } + + /** + * Writes the specified byte to the specified output stream + * and copies it to the file. + * + * @param b the byte to be written. + * @throws IOException If an I/O error occurs. + */ + @Override + public void write(int b) throws IOException { + fileStream.write(b); + outputStream.write(b); + } + + /** + * Flushes this output stream and forces any buffered output bytes + * to be written out. + * The <code>flush</code> method of <code>TeeStream</code> flushes + * the specified output stream and the file output stream. + * + * @throws IOException if an I/O error occurs. + */ + @Override + public void flush() throws IOException { + outputStream.flush(); + fileStream.flush(); + } + + /** + * Closes underlying streams and resources. + * The external output stream won't be closed. + * This method is the member of AutoCloseable interface and + * it will be invoked automatically after the try-with-resources block. + * + * @throws IOException If an I/O error occurs. + */ + @Override + public void close() throws IOException { + try (OutputStream file = fileStream) { + flush(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/src/Unzip.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.*; + +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + +/** + * Extract (unzip) a file to the current directory. + */ +public class Unzip { + + /** + * The main method for the Unzip program. Run the program with an empty + * argument list to see possible arguments. + * + * @param args the argument list for {@code Unzip}. + */ + public static void main(String[] args) { + if (args.length != 1) { + System.out.println("Usage: Unzip zipfile"); + } + final Path destDir = Paths.get("."); + /* + * Create AutoCloseable FileSystem. It will be closed automatically + * after the try block. + */ + try (FileSystem zipFileSystem = FileSystems.newFileSystem(Paths.get(args[0]), null)) { + + Path top = zipFileSystem.getPath("/"); + Files.walk(top).skip(1).forEach(file -> { + Path target = destDir.resolve(top.relativize(file).toString()); + System.out.println("Extracting " + target); + try { + Files.copy(file, target, REPLACE_EXISTING); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } catch (UncheckedIOException | IOException e) { + e.printStackTrace(); + System.exit(1); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/src/ZipCat.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation, and proper error handling, might not be present in + * this sample code. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * Prints data of the specified file to standard output from a zip archive. + */ +public class ZipCat { + + /** + * The main method for the ZipCat program. Run the program with an empty + * argument list to see possible arguments. + * + * @param args the argument list for ZipCat + */ + public static void main(String[] args) { + if (args.length != 2) { + System.out.println("Usage: ZipCat zipfile fileToPrint"); + } + /* + * Creates AutoCloseable FileSystem and BufferedReader. + * They will be closed automatically after the try block. + * If reader initialization fails, then zipFileSystem will be closed + * automatically. + */ + try (FileSystem zipFileSystem + = FileSystems.newFileSystem(Paths.get(args[0]),null); + InputStream input + = Files.newInputStream(zipFileSystem.getPath(args[1]))) { + byte[] buffer = new byte[1024]; + int len; + while ((len = input.read(buffer)) != -1) { + System.out.write(buffer, 0, len); + } + + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } +}
--- a/src/solaris/native/common/jni_util_md.c Wed Jan 22 16:15:39 2014 +0400 +++ b/src/solaris/native/common/jni_util_md.c Thu Feb 06 13:28:20 2014 -0800 @@ -23,6 +23,8 @@ * questions. */ +#include <string.h> + #include "jni.h" #include "jni_util.h" #include "dlfcn.h" @@ -40,7 +42,11 @@ if (procHandle != NULL) { return procHandle; } +#ifdef __APPLE__ + procHandle = (void*)dlopen(NULL, RTLD_FIRST); +#else procHandle = (void*)dlopen(NULL, RTLD_LAZY); +#endif return procHandle; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/Test.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, 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 8032585 8033278 + * @summary JSR292: IllegalAccessError when attempting to invoke protected method from different package + * + * @compile p1/T2.java p2/T3.java + * @run main/othervm p2.T3 + */ +public class Test {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/p1/T2.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package p1; + +import p2.T3; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.util.concurrent.Callable; + +class T1 { + protected void m1() {} + protected static void m2() {} +} + +public class T2 extends T1 { + public static void main(String[] args) throws Throwable { + Lookup LOOKUP = T3.lookup(); + Class<IllegalAccessException> IAE = IllegalAccessException.class; + + assertFailure(IAE, () -> LOOKUP.findVirtual(T1.class, "m1", MethodType.methodType(void.class))); + assertFailure(IAE, () -> LOOKUP.findStatic(T1.class, "m2", MethodType.methodType(void.class))); + + assertSuccess(() -> LOOKUP.findVirtual(T2.class, "m1", MethodType.methodType(void.class))); + assertSuccess(() -> LOOKUP.findVirtual(T3.class, "m1", MethodType.methodType(void.class))); + + assertSuccess(() -> LOOKUP.findStatic(T2.class, "m2", MethodType.methodType(void.class))); + assertSuccess(() -> LOOKUP.findStatic(T3.class, "m2", MethodType.methodType(void.class))); + + assertFailure(IAE, () -> LOOKUP.unreflect(T1.class.getDeclaredMethod("m1"))); + assertFailure(IAE, () -> LOOKUP.unreflect(T1.class.getDeclaredMethod("m2"))); + + System.out.println("TEST PASSED"); + } + + public static void assertFailure(Class<? extends Throwable> expectedError, Callable r) { + try { + r.call(); + } catch(Throwable e) { + if (expectedError.isAssignableFrom(e.getClass())) { + return; // expected error + } else { + throw new Error("Unexpected error type: "+e.getClass()+"; expected type: "+expectedError, e); + } + } + throw new Error("No error"); + } + + public static void assertSuccess(Callable r) { + try { + r.call(); + } catch(Throwable e) { + throw new Error("Unexpected error", e); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/p2/T3.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package p2; + +import p1.T2; + +import java.lang.invoke.MethodHandles; + +public class T3 extends T2 { + public static MethodHandles.Lookup lookup() { return MethodHandles.lookup(); } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/lambda/T8032697.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, 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 8032697 + * @summary Issues with Lambda + */ + +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.LambdaConversionException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import T8032697_anotherpkg.T8032697_A; + +public class T8032697 extends T8032697_A { + + interface I { + int m(); + } + + interface IA { + int m(T8032697_A x); + } + + static MethodHandles.Lookup l; + static MethodHandle h; + private static MethodType mt(Class<?> k) { return MethodType.methodType(k); } + private static MethodType mt(Class<?> k, Class<?> k2) { return MethodType.methodType(k, k2); } + private static boolean mf(MethodType mti, MethodType mtf) { + try { + LambdaMetafactory.metafactory(l, "m", mti,mtf,h,mtf); + } catch(LambdaConversionException e) { + return true; + } + return false; + } + + public static void main(String[] args) throws Throwable { + l = MethodHandles.lookup(); + h = l.findVirtual(T8032697_A.class, "f", mt(int.class)); + if (mf(mt(I.class, T8032697.class), mt(int.class))) throw new AssertionError("Error: Should work"); + if (mf(mt(IA.class), mt(int.class, T8032697.class))) throw new AssertionError("Error: Should work"); + if (!mf(mt(I.class, T8032697_A.class), mt(int.class))) throw new AssertionError("Error: Should fail"); + if (!mf(mt(IA.class), mt(int.class, T8032697_A.class))) throw new AssertionError("Error: Should fail"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/lambda/T8032697_anotherpkg/T8032697_A.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package T8032697_anotherpkg; + +public class T8032697_A { + protected final int f() { return 2; } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/lambda/T8032704.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, 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 8032704 + * @summary Issues with lib perm in Lambda + */ + +import java.io.Closeable; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.LambdaConversionException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class T8032704 { + + public static void here() {} + static MethodHandle h; + private static MethodType mt(Class<?> k) { return MethodType.methodType(k); } + private static boolean mf(MethodHandles.Lookup l) { + try { + LambdaMetafactory.metafactory(l, "close", + mt(Closeable.class),mt(void.class),h,mt(void.class)); + } catch(LambdaConversionException e) { + return true; + } + return false; + } + + public static void main(String[] args) throws Throwable { + MethodHandles.Lookup ll = MethodHandles.lookup(); + h = ll.findStatic(T8032704.class, "here", mt(void.class)); + if (mf(ll)) throw new AssertionError("Error: Should work"); + if (!mf(MethodHandles.publicLookup())) throw new AssertionError("Error: Should fail - public"); + if (!mf(ll.in(T8032704other.class))) throw new AssertionError("Error: Should fail - other"); + if (!mf(ll.in(Thread.class))) throw new AssertionError("Error: Should fail - Thread"); + } +} + +class T8032704other {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/lambda/T8032711.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, 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 8032711 + * @summary Issue with Lambda in handling + */ + +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.LambdaConversionException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class T8032711 { + + interface I { + void m(); + } + + static void here() {} + static MethodHandles.Lookup l; + static MethodHandle h; + private static MethodType mt(Class<?> k) { return MethodType.methodType(k); } + private static boolean mf(Class<?> k) { + try { + LambdaMetafactory.metafactory(l, "m", + mt(I.class),mt(k),h,mt(void.class)); + } catch(LambdaConversionException e) { + return true; + } + return false; + } + + public static void main(String[] args) throws Throwable { + l = MethodHandles.lookup(); + h = l.findStatic(T8032711.class, "here", mt(void.class)); + if (mf(void.class)) throw new AssertionError("Error: Should work"); + if (!mf(String.class)) throw new AssertionError("Error: Should fail"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/tools/jarsigner/EntriesOrder.java Thu Feb 06 13:28:20 2014 -0800 @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014, 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 8031572 + * @summary jarsigner -verify exits with 0 when a jar file is not properly signed + */ + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.cert.Certificate; +import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class EntriesOrder { + + public static void main(String[] args) throws Exception { + + String[] entries = { + "META-INF/", + "META-INF/MANIFEST.MF", + "META-INF/A.RSA", + "META-INF/A.SF", + "META-INF/inf", + "a"}; + + Map<String,byte[]> content = new HashMap<>(); + + // We will create a jar containing entries above. Try all permutations + // and confirm 1) When opened as a JarFile, we can always get 3 signed + // ones (MANIFEST, inf, a), and 2) When opened as a JarInputStream, + // when the order is correct (MANIFEST at beginning, followed by RSA/SF, + // directory ignored), we can get 2 signed ones (inf, a). + + // Prepares raw files + Files.write(Paths.get("a"), "a".getBytes()); + Files.createDirectory(Paths.get("META-INF/")); + Files.write(Paths.get("META-INF/inf"), "inf".getBytes()); + + // Pack, sign, and extract to get all files + sun.tools.jar.Main m = + new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!m.run("cvf a.jar a META-INF/inf".split(" "))) { + throw new Exception("jar creation failed"); + } + sun.security.tools.keytool.Main.main( + ("-keystore jks -storepass changeit -keypass changeit -dname" + + " CN=A -alias a -genkeypair -keyalg rsa").split(" ")); + sun.security.tools.jarsigner.Main.main( + "-keystore jks -storepass changeit a.jar a".split(" ")); + m = new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!m.run("xvf a.jar".split(" "))) { + throw new Exception("jar extraction failed"); + } + + // Data + for (String s: entries) { + if (!s.endsWith("/")) { + content.put(s, Files.readAllBytes(Paths.get(s))); + } + } + + // Test + for (List<String> perm: Permute(entries)) { + + // Recreate a jar + try (ZipOutputStream zos + = new ZipOutputStream(new FileOutputStream("x.jar"))) { + for (String e: perm) { + zos.putNextEntry(new ZipEntry(e)); + if (Paths.get(e).toFile().isDirectory()) continue; + zos.write(content.get(e)); + } + } + + // Open with JarFile, number of signed entries should be 3. + int cc = 0; + try (JarFile jf = new JarFile("x.jar")) { + Enumeration<JarEntry> jes = jf.entries(); + while (jes.hasMoreElements()) { + JarEntry je = jes.nextElement(); + sun.misc.IOUtils.readFully(jf.getInputStream(je), -1, true); + Certificate[] certs = je.getCertificates(); + if (certs != null && certs.length > 0) { + cc++; + } + } + } + + if (cc != 3) { + System.out.println(perm + " - jf - " + cc); + throw new Exception(); + } + + // Open with JarInputStream + int signed; + + perm.remove("META-INF/"); + if (perm.get(0).equals("META-INF/MANIFEST.MF") && + perm.get(1).contains("/A.") && + perm.get(2).contains("/A.")) { + signed = 2; // Good order + } else { + signed = 0; // Bad order. In this case, the number of signed + // entries is not documented. Just test impl. + } + + cc = 0; + try (JarInputStream jis + = new JarInputStream(new FileInputStream("x.jar"))) { + while (true) { + JarEntry je = jis.getNextJarEntry(); + if (je == null) break; + sun.misc.IOUtils.readFully(jis, -1, true); + Certificate[] certs = je.getCertificates(); + if (certs != null && certs.length > 0) { + cc++; + } + } + } + + if (cc != signed) { + System.out.println(perm + " - jis - " + cc + " " + signed); + throw new Exception(); + } + } + } + + // Helper method to return all permutations of an array. Each output can + // be altered without damaging the iteration process. + static Iterable<List<String>> Permute(String[] entries) { + return new Iterable<List<String>>() { + + int s = entries.length; + long c = factorial(s) - 1; // number of permutations + + private long factorial(int n) { + return (n == 1) ? 1: (n * factorial(n-1)); + } + + @Override + public Iterator<List<String>> iterator() { + return new Iterator<List<String>>() { + @Override + public boolean hasNext() { + return c >= 0; + } + + @Override + public List<String> next() { + if (c < 0) return null; + List<String> result = new ArrayList<>(s); + LinkedList<String> source = new LinkedList<>( + Arrays.asList(entries)); + // Treat c as a integer with different radixes at + // different digits, i.e. at digit 0, radix is s; + // at digit 1, radix is s-1. Thus a s-digit number + // is able to represent s! different values. + long n = c; + for (int i=s; i>=1; i--) { + int x = (int)(n % i); + result.add(source.remove(x)); + n = n / i; + } + c--; + return result; + } + }; + } + }; + } +}