# HG changeset patch # User lana # Date 1391204848 28800 # Node ID f644211c59fd7c1d0c81239c55b31e1d377d7650 # Parent f777d83e043350c63b1158caec16447406383565# Parent f684c97738589fc8f8047dfdb2b897c9cfb67721 Merge diff -r f777d83e0433 -r f644211c59fd src/share/classes/sun/invoke/util/VerifyAccess.java --- a/src/share/classes/sun/invoke/util/VerifyAccess.java Thu Jan 30 12:17:07 2014 -0800 +++ b/src/share/classes/sun/invoke/util/VerifyAccess.java Fri Jan 31 13:47:28 2014 -0800 @@ -90,33 +90,26 @@ 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 && isSuperClass(defc, lookupClass)) return true; diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Device.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Device.java Fri Jan 31 13:47:28 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 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 getSupportedModules() { + return Collections.unmodifiableMap(supportedModules); + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Kettle.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Kettle.xml Fri Jan 31 13:47:28 2014 -0800 @@ -0,0 +1,57 @@ + + + + + + + DISPLAY + 2 + + + THERMOMETER + 1 + + + CLOCK + 4 + + + \ No newline at end of file diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Module.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Module.java Fri Jan 31 13:47:28 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; +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/PluginChecker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/PluginChecker.java Fri Jan 31 13:47:28 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 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 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; + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Require.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/Require.java Fri Jan 31 13:47:28 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; +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/RequireContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/PluginChecker/src/checker/RequireContainer.java Fri Jan 31 13:47:28 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(); +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/BoilerPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/BoilerPlugin.java Fri Jan 31 13:47:28 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. + } + +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/ExtendedBoilerPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/ExtendedBoilerPlugin.java Fri Jan 31 13:47:28 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 + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/TimerPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/DependencyChecker/Plugins/src/plugins/TimerPlugin.java Fri Jan 31 13:47:28 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 + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/Validator/src/PositiveIntegerSupplier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/PositiveIntegerSupplier.java Fri Jan 31 13:47:28 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 { + + /** + * Returns a string representation of a positive integer. + * + * @return string representation of a positive integer. + */ + @Override + public String get() { + return "20005"; //random number + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/Validator/src/SupplierValidator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/SupplierValidator.java Fri Jan 31 13:47:28 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; + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/Validator/src/Validate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/Validate.java Fri Jan 31 13:47:28 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(); +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/Validator/src/Validator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/Validator/src/Validator.java Fri Jan 31 13:47:28 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; + +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/annotations/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/annotations/index.html Fri Jan 31 13:47:28 2014 -0800 @@ -0,0 +1,67 @@ + + + + Repeating Annotations Demo + + +

Repeating Annotations Demo

+ +

+ This demo shows how to use repeating annotations at runtime and at compile time. +

+ +
    +
  • Dependency checker.

    + +

    + 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:

    + + javac -cp "PluginChecker.jar" -processor checker.PluginChecker -Adevice=Kettle.xml -proc:only <source + files> + +

    + where PluginChecker.jar - path to jar file that contains PluginChecker annotation processor + class.
    + Kettle.xml - path to device descriptor Kettle.xml
    + <source files> - source files in Plugins/src +

    + For more information, see the source files. +

    + + +
  • Validator.

    + +

    + 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. +

    + +

    +

    +

    + Sources: Validator/src/ +
+ + \ No newline at end of file diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/BulkDataOperations/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/index.html Fri Jan 31 13:47:28 2014 -0800 @@ -0,0 +1,49 @@ + + + + Bulk Data Operations Demo + + +

Bulk Data Operations Demo

+ +

+ 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. +

+ +
    +
  • CSV Processor

    + +

    + Analyzes a CSV file, finds and collects useful information, computes + different statistics. For more information, see the source file. +

    + Source: src/CSVProcessor.java +
  • Grep

    + +

    + Behaves like the standard Linux tool Grep. For more information, see + the source file. +

    + Source: src/Grep.java +
  • PasswordGenerator

    + +

    + Produces a password of desired length. For more information see + source file. +

    + Source: src/PasswordGenerator.java +
  • WC

    + +

    + Counts newlines, words, characters, and the maximum line length of a + text file. For more information, see the source + file. +

    + Source: src/WC.java +
+ + \ No newline at end of file diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/BulkDataOperations/src/CSVProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/CSVProcessor.java Fri Jan 31 13:47:28 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: + *
    + *
  • 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.
  • + *
  • Static method reference for printing values.
  • + *
  • Try-with-resources feature for closing files.
  • + *
  • Switch by String feature.
  • + *
  • Other new APIs: Pattern.asPredicate(), BinaryOperator + * BufferedReader.lines(), Collection.forEach(...), Comparator.comparing(...), + * Comparator.reversed(), Arrays.stream(...).
  • + *
+ * + */ +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 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 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 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 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 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 { + + + /* + * 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 maxOperator; + private final BinaryOperator minOperator; + private final int column; + + public Statistics(int column) { + this.column = column; + Comparator 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 supplier() { + return () -> new Statistics(column); + } + + @Override + public BiConsumer accumulator() { + return Statistics::accept; + } + + @Override + public BinaryOperator combiner() { + return Statistics::combine; + + } + + @Override + public Function finisher() { + return stat -> stat; + } + + @Override + public Set 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; + } + + } + +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/BulkDataOperations/src/Grep.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/Grep.java Fri Jan 31 13:47:28 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: + *
    + *
  • Lambda and bulk operations. Working with streams: + * map(...),filter(...),flatMap(...),limit(...) methods.
  • + *
  • Static method reference for printing values.
  • + *
  • New Collections API forEach(...) method.
  • + *
  • Try-with-resources feature.
  • + *
  • new Files.walk(...), Files.lines(...) API.
  • + *
  • Streams that need to be closed.
  • + *
+ * + */ +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 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 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 path2Lines(Path path) { + try { + return Files.lines(path); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/BulkDataOperations/src/PasswordGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/PasswordGenerator.java Fri Jan 31 13:47:28 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: + *
    + *
  • Method references.
  • + *
  • 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.
  • + *
+ * + */ +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 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(); + } + +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/BulkDataOperations/src/WC.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/BulkDataOperations/src/WC.java Fri Jan 31 13:47:28 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: + *
    + *
  • 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.
  • + *
  • Constructor reference.
  • + *
  • Try-with-resources feature.
  • + *
+ * + */ +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 { + /* + * @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(); + } + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/DefaultMethods/ArrayIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/ArrayIterator.java Fri Jan 31 13:47:28 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 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 Iterator iterator(final E[] array) { + return new Iterator() { + /** + * 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 it = ArrayIterator.iterator( + new String[]{"one", "two", "three"}); + + while (it.hasNext()) { + System.out.println(it.next()); + } + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/DefaultMethods/DiamondInheritance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/DiamondInheritance.java Fri Jan 31 13:47:28 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 default methods. + * If there's not already a unique method implementation to inherit, + * you must provide it. The inheritance diagram is similar to the following: + *
+ *                   Animal
+ *                    /   \
+ *                 Horse   Bird
+ *                    \   /
+ *                   Pegasus
+ * 
+ * + * Both {@link Horse} and {@link Bird} interfaces implements the go + * method. The {@link Pegasus} class have to overrides the + * go method. + * + * The new syntax of super-call is used here: + *
+ *     <interface_name>.super.<method>(...);
+ *     For example:  Horse.super.go();
+ * 
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()); + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/DefaultMethods/Inheritance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/Inheritance.java Fri Jan 31 13:47:28 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 default methods. There are two simple rules: + *
    + *
  • Class wins. If the superclass has a concrete or abstract declaration of + * this method, then it is preferred over all defaults.
  • + *
  • Subtype wins. If an interface extends another interface, and both provide + * a default, then the more specific interface wins.
  • + *
+ */ +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. + *
+     *      System.out.println(new Tuna().swim()); //"Tuna swims under water" output is suspected here
+     * 
+ */ + 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 + *
+     *      //"I can swim on the surface of the water." output is suspected here
+     *      System.out.println(new Duck().swim());
+     * 
+ */ + 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()); + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/DefaultMethods/MixIn.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/MixIn.java Fri Jan 31 13:47:28 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:
+         * State of the: <Class Name>
+         * <member name> : <value>
+         * ...
+         * 
+ */ + 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()); + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/DefaultMethods/Reflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/Reflection.java Fri Jan 31 13:47:28 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 + * default methods. Since Java SE 8, a new method is added into the class + * java.lang.reflect.Method, with which you can reflectively + * determine whether or not a default method provided by an interface + * (Method.isDefault()). + */ +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: + *
    + *
  • 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)
  • + *
  • the {@link #eat} is a simple default method that is not overridden + * in this class. + *
  • + *
+ */ + 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(); + }); + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/lambda/DefaultMethods/SimplestUsage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/lambda/DefaultMethods/SimplestUsage.java Fri Jan 31 13:47:28 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 default methods. + */ +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()); + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/try-with-resources/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/index.html Fri Jan 31 13:47:28 2014 -0800 @@ -0,0 +1,36 @@ + + + + + Try-with-Resources Feature Demo + + +

Try-with-Resources Feature Demo

+ +

+ This demo shows how to use the try-with-resources feature introduced in JDK7. +

+ +
    +
  • Custom AutoCloseable.

    + +

    + Shows how to use a custom resource with the try-with-resources construct. + For more information, see the source file. +

    + Source: src/CustomAutoCloseableSample.java + +
  • Unzip

    + +

    + Extracts archived files. For more information, see the source file. +

    + Source: src/Unzip.java +
  • ZipCat

    + +

    Prints data about a specified file from an archive. For more information, see the source file.

    + Source: src/ZipCat.java + +
+ + \ No newline at end of file diff -r f777d83e0433 -r f644211c59fd src/share/sample/try-with-resources/src/CustomAutoCloseableSample.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/src/CustomAutoCloseableSample.java Fri Jan 31 13:47:28 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 flush method of TeeStream 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(); + } + } + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/try-with-resources/src/Unzip.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/src/Unzip.java Fri Jan 31 13:47:28 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); + } + } +} diff -r f777d83e0433 -r f644211c59fd src/share/sample/try-with-resources/src/ZipCat.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/sample/try-with-resources/src/ZipCat.java Fri Jan 31 13:47:28 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); + } + } +} diff -r f777d83e0433 -r f644211c59fd test/java/lang/invoke/ProtectedMemberDifferentPackage/Test.java --- a/test/java/lang/invoke/ProtectedMemberDifferentPackage/Test.java Thu Jan 30 12:17:07 2014 -0800 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/Test.java Fri Jan 31 13:47:28 2014 -0800 @@ -24,7 +24,7 @@ /** * @test - * @bug 8032585 + * @bug 8032585 8033278 * @summary JSR292: IllegalAccessError when attempting to invoke protected method from different package * * @compile p1/T2.java p2/T3.java diff -r f777d83e0433 -r f644211c59fd test/java/lang/invoke/ProtectedMemberDifferentPackage/p1/T2.java --- a/test/java/lang/invoke/ProtectedMemberDifferentPackage/p1/T2.java Thu Jan 30 12:17:07 2014 -0800 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/p1/T2.java Fri Jan 31 13:47:28 2014 -0800 @@ -23,8 +23,57 @@ */ 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 m() { System.out.println("T1.m");} + protected void m1() {} + protected static void m2() {} } -public class T2 extends T1 {} +public class T2 extends T1 { + public static void main(String[] args) throws Throwable { + Lookup LOOKUP = T3.lookup(); + Class 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 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); + } + } +} diff -r f777d83e0433 -r f644211c59fd test/java/lang/invoke/ProtectedMemberDifferentPackage/p2/T3.java --- a/test/java/lang/invoke/ProtectedMemberDifferentPackage/p2/T3.java Thu Jan 30 12:17:07 2014 -0800 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/p2/T3.java Fri Jan 31 13:47:28 2014 -0800 @@ -25,13 +25,8 @@ import p1.T2; -import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; public class T3 extends T2 { - public static void main(String[] args) throws Throwable { - MethodHandles.lookup().findVirtual(T3.class, "m", MethodType.methodType(void.class)); - System.out.println("TEST PASSED"); - } + public static MethodHandles.Lookup lookup() { return MethodHandles.lookup(); } }