This commit is contained in:
J. Duke 2017-07-05 21:30:59 +02:00
commit 91b5bedc63
491 changed files with 86614 additions and 2600 deletions

View File

@ -354,3 +354,4 @@ c7be2a78c31b3b6132f2f5e9e4b3d3bb1c20245c jdk-9+108
1787bdaabb2b6f4193406e25a50cb0419ea8e8f3 jdk-9+109
925be13b3740d07a5958ccb5ab3c0ae1baba7055 jdk-9+110
f900d5afd9c83a0df8f36161c27c5e4c86a66f4c jdk-9+111
03543a758cd5890f2266e4b9678378a925dde22a jdk-9+112

View File

@ -241,8 +241,7 @@ var getJibProfilesProfiles = function (input, common) {
target_os: "linux",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"),
configure_args: common.configure_args,
configure_args: concat(common.configure_args, "--with-zlib=system"),
configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
@ -251,8 +250,8 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "x86",
build_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"),
configure_args: concat(common.configure_args, common.configure_args_32bit),
configure_args: concat(common.configure_args, "--with-zlib=system"),
configure_args: concat(common.configure_args, common.configure_args_32bit,
"--with-zlib=system"),
make_args: common.make_args
},
@ -260,8 +259,7 @@ var getJibProfilesProfiles = function (input, common) {
target_os: "macosx",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"),
configure_args: common.configure_args,
configure_args: concat(common.configure_args, "--with-zlib=system"),
configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
@ -269,8 +267,7 @@ var getJibProfilesProfiles = function (input, common) {
target_os: "solaris",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "cups"),
configure_args: common.configure_args,
configure_args: concat(common.configure_args, "--with-zlib=system"),
configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},
@ -278,8 +275,7 @@ var getJibProfilesProfiles = function (input, common) {
target_os: "solaris",
target_cpu: "sparcv9",
dependencies: concat(common.dependencies, "devkit", "cups"),
configure_args: common.configure_args,
configure_args: concat(common.configure_args, "--with-zlib=system"),
configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args
},

View File

@ -514,3 +514,4 @@ c5146d4da417f76edfc43097d2e2ced042a65b4e jdk-9+107
7e7e50ac4faf19899fc811569e32cfa478759ebb jdk-9+109
2f5d1578b24060ea06bd1f340a124db95d1475b2 jdk-9+110
c558850fac5750d8ca98a45180121980f57cdd28 jdk-9+111
76582e8dc9e6374e4f99ab797c8d364b6e9449b4 jdk-9+112

View File

@ -7,3 +7,5 @@
^make/netbeans/.*/dist/
^.hgtip
.DS_Store
.*/JTreport/.*
.*/JTwork/.*

View File

@ -354,3 +354,4 @@ eee1ced1d8e78293f2a004af818ca474387dbebf jdk-9+103
1c7bad0798900fe58f4db01ae7ffdc84f5baee8c jdk-9+109
9417e1bcded6af5532c3b26235437ab227758877 jdk-9+110
b2a69d66dc65ad1d3aeb3bd362cf5bb0deba040e jdk-9+111
1565a0efe6f0ca411a6df277df1e069431c60988 jdk-9+112

View File

@ -63,11 +63,9 @@ $(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR_LD, \
ifeq ($(BOOT_JDK_MODULAR), true)
BREAK_ITERATOR_BOOTCLASSPATH := -Xpatch:$(BREAK_ITERATOR_CLASSES) \
-XaddExports:$(subst $(SPACE),$(COMMA),$(strip \
java.base/sun.text=ALL-UNNAMED \
java.base/sun.text.resources=ALL-UNNAMED \
jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
))
-XaddExports:java.base/sun.text=ALL-UNNAMED \
-XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
-XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED
else
BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \
$(BREAK_ITERATOR_CLASSES)/java.base \

View File

@ -55,7 +55,6 @@ GENSRC_JAVA_BASE += $(LIST_RESOURCE_BUNDLE) $(SUN_UTIL)
# copied to zh_HK locale.
$(eval $(call SetupCopy-zh_HK,COPY_ZH_HK, \
$(addprefix $(JDK_TOPDIR)/src/java.base/share/classes/, \
sun/misc/resources/Messages_zh_TW.java \
sun/security/util/AuthResources_zh_TW.java \
sun/security/util/Resources_zh_TW.java)))

View File

@ -0,0 +1,15 @@
This NetBeans project corresponds to client sanity test suite in jdk/test/sanity/client.
It simplifies working on the suite in NetBeans.
It also includes the following custom tasks:
prepare-bundle creates dist/sanity.zip containing standalone bundle of the suite
run-jemmy-browser runs Jemmy browser for the ButtonDemo (hardcoded in build.xml file)
The tool allows to explore the UI hierarchy.
There is no task to run tests using JTReg. Please refer to corresponding README file
in the client sanity test suite folder on how to run the tests.
Contact alexander.kouznetsov@oracle.com in case of issues.

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="SanityTests" default="default" basedir=".">
<description>Builds, tests, and runs the project SanityTests.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="SanityTests-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
<target name="prepare-bundle" depends="init">
<zip zipfile="${dist.dir}/sanity.zip">
<fileset dir="../../../test" includes="sanity/client/SwingSet/**"/>
<fileset dir="../../../test" includes="sanity/client/lib/**"/>
<fileset dir="../../../test" includes="sanity/client/ReadMe.txt"/>
<fileset dir="../../../test" includes="sanity/client/TEST.properties"/>
<mappedresources>
<fileset dir="../../../test/sanity/client" includes="TEST.ROOT.template"/>
<globmapper from="TEST.ROOT.template" to="TEST.ROOT" />
</mappedresources>
</zip>
</target>
<target name="run-jemmy-browser" depends="init">
<java
classpath="${run.classpath}"
classname="org.netbeans.jemmy.explorer.GUIBrowser"
args="com.sun.swingset3.demos.button.ButtonDemo"/>
</target>
</project>

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
build.xml.data.CRC32=0f9d9977
build.xml.script.CRC32=f902e8b8
build.xml.stylesheet.CRC32=8064a381@1.75.2.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=55414227
nbproject/build-impl.xml.script.CRC32=c12f9d04
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48

View File

@ -0,0 +1,79 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=SanityTests
application.vendor=akouznet
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# Files in build.classes.dir which should be excluded from distribution jar
dist.archive.excludes=
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/SanityTests.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=*.cfg
includes=**
jar.compress=false
javac.classpath=\
${libs.testng.classpath}
# Space-separated list of extra javac options
javac.compilerargs=-Xmaxwarns 9999 -Xlint:all -Xlint:-serial
javac.deprecation=false
javac.external.vm=false
javac.processorpath=\
${javac.classpath}
javac.source=1.8
javac.target=1.8
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=-ea
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src
src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src
src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src
src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Jemmy2Ext\\src

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>SanityTests</name>
<source-roots>
<root id="src.src3.dir" name="lib\jemmy\src"/>
<root id="src.src4.dir" name="lib\Jemmy2Ext\src"/>
<root id="src.src2.dir" name="lib\SwingSet3\src"/>
<root id="src.src.dir" name="SwingSet\src"/>
</source-roots>
<test-roots/>
</data>
<references xmlns="http://www.netbeans.org/ns/ant-project-references/2"/>
</configuration>
</project>

View File

@ -31,7 +31,13 @@ include RMICompilation.gmk
##########################################################################################
RMIC := $(JAVA) $(INTERIM_OVERRIDE_MODULES_ARGS) sun.rmi.rmic.Main
ifeq ($(BOOT_JDK_MODULAR), true)
RMIC_MAIN_CLASS := -m jdk.rmic/sun.rmi.rmic.Main
else
RMIC_MAIN_CLASS := sun.rmi.rmic.Main
endif
RMIC := $(JAVA) $(INTERIM_OVERRIDE_MODULES_ARGS) $(RMIC_MAIN_CLASS)
CLASSES_DIR := $(JDK_OUTPUTDIR)/modules
# NOTE: If the smart javac dependency management is reintroduced, these classes risk

View File

@ -25,25 +25,27 @@
package build.tools.module;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* A build tool to extend the module-info.java in the source tree
* for platform-specific exports, uses, and provides and write
* to the specified output file.
* A build tool to extend the module-info.java in the source tree for
* platform-specific exports, uses, and provides and write to the specified
* output file. Injecting platform-specific requires is not supported.
*
* GenModulesList build tool currently generates the modules.list from
* the module-info.java from the source tree that will be used for
* the make target and dependences.
*
* The build currently invokes gensrc-$MODULE.gmk after modules.list
* is generated. Hence, platform-specific requires is not supported.
* The extra exports, uses, provides can be specified in module-info.java.extra
* files and GenModuleInfoSource will be invoked for each module that has
* module-info.java.extra in the source directory.
*/
public class GenModuleInfoSource {
private final static String USAGE =
@ -57,17 +59,32 @@ public class GenModuleInfoSource {
public static void main(String... args) throws Exception {
Path outfile = null;
Path moduleInfoJava = null;
Map<String, Set<String>> options = new HashMap<>();
GenModuleInfoSource genModuleInfo = new GenModuleInfoSource();
// validate input arguments
for (int i = 0; i < args.length; i++){
String option = args[i];
if (option.startsWith("-")) {
String arg = args[++i];
if (option.equals("-exports") ||
option.equals("-uses") ||
option.equals("-provides")) {
options.computeIfAbsent(option, _k -> new HashSet<>()).add(arg);
if (option.equals("-exports")) {
int index = arg.indexOf('/');
if (index > 0) {
String pn = arg.substring(0, index);
String mn = arg.substring(index + 1, arg.length());
genModuleInfo.exportTo(pn, mn);
} else {
genModuleInfo.export(arg);
}
} else if (option.equals("-uses")) {
genModuleInfo.use(arg);
} else if (option.equals("-provides")) {
int index = arg.indexOf('/');
if (index <= 0) {
throw new IllegalArgumentException("invalid -provide argument: " + arg);
}
String service = arg.substring(0, index);
String impl = arg.substring(index + 1, arg.length());
genModuleInfo.provide(service, impl);
} else if (option.equals("-o")) {
outfile = Paths.get(arg);
} else {
@ -87,48 +104,145 @@ public class GenModuleInfoSource {
System.err.println(USAGE);
System.exit(-1);
}
// read module-info.java
Module.Builder builder = ModuleInfoReader.builder(moduleInfoJava);
augment(builder, options);
// generate new module-info.java
Module module = builder.build();
genModuleInfo.generate(moduleInfoJava, outfile);
}
private final Set<String> exports = new HashSet<>();
private final Map<String, Set<String>> exportsTo = new HashMap<>();
private final Set<String> uses = new HashSet<>();
private final Map<String, Set<String>> provides = new HashMap<>();
GenModuleInfoSource() {
}
private void export(String p) {
Objects.requireNonNull(p);
if (exports.contains(p) || exportsTo.containsKey(p)) {
throw new RuntimeException("duplicated exports: " + p);
}
exports.add(p);
}
private void exportTo(String p, String mn) {
Objects.requireNonNull(p);
Objects.requireNonNull(mn);
if (exports.contains(p)) {
throw new RuntimeException("unqualified exports already exists: " + p);
}
exportsTo.computeIfAbsent(p, _k -> new HashSet<>()).add(mn);
}
private void use(String service) {
uses.add(service);
}
private void provide(String s, String impl) {
provides.computeIfAbsent(s, _k -> new HashSet<>()).add(impl);
}
private void generate(Path sourcefile, Path outfile) throws IOException {
Path parent = outfile.getParent();
if (parent != null)
Files.createDirectories(parent);
try (BufferedWriter writer = Files.newBufferedWriter(outfile)) {
writer.write(module.toString());
}
}
List<String> lines = Files.readAllLines(sourcefile);
try (BufferedWriter bw = Files.newBufferedWriter(outfile);
PrintWriter writer = new PrintWriter(bw)) {
int lineNumber = 0;
for (String l : lines) {
lineNumber++;
String[] s = l.trim().split("\\s+");
String keyword = s[0].trim();
int nextIndex = keyword.length();
String exp = null;
int n = l.length();
switch (keyword) {
case "exports":
boolean inExportsTo = false;
// assume package name immediately after exports
exp = s[1].trim();
if (s.length >= 3) {
nextIndex = l.indexOf(exp, nextIndex) + exp.length();
if (s[2].trim().equals("to")) {
inExportsTo = true;
n = l.indexOf("to", nextIndex) + "to".length();
} else {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed: " + s[2]);
}
}
private static void augment(Module.Builder builder, Map<String, Set<String>> options) {
for (String opt : options.keySet()) {
if (opt.equals("-exports")) {
for (String arg : options.get(opt)) {
int index = arg.indexOf('/');
if (index > 0) {
String pn = arg.substring(0, index);
String mn = arg.substring(index + 1, arg.length());
builder.exportTo(pn, mn);
} else {
builder.export(arg);
}
}
} else if (opt.equals("-uses")) {
options.get(opt).stream()
.forEach(builder::use);
} else if (opt.equals("-provides")) {
for (String arg : options.get(opt)) {
int index = arg.indexOf('/');
if (index <= 0) {
throw new IllegalArgumentException("invalid -provide argument: " + arg);
}
String service = arg.substring(0, index);
String impl = arg.substring(index + 1, arg.length());
builder.provide(service, impl);
// inject the extra targets after "to"
if (inExportsTo) {
writer.println(injectExportTargets(exp, l, n));
} else {
writer.println(l);
}
break;
case "to":
if (exp == null) {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed");
}
n = l.indexOf("to", nextIndex) + "to".length();
writer.println(injectExportTargets(exp, l, n));
break;
case "}":
doAugments(writer);
// fall through
default:
writer.println(l);
// reset exports
exp = null;
}
}
}
}
private String injectExportTargets(String pn, String exp, int pos) {
Set<String> targets = exportsTo.remove(pn);
if (targets != null) {
StringBuilder sb = new StringBuilder();
// inject the extra targets after the given pos
sb.append(exp.substring(0, pos))
.append("\n\t")
.append(targets.stream()
.collect(Collectors.joining(",", "", ",")))
.append(" /* injected */");
if (pos < exp.length()) {
// print the remaining statement followed "to"
sb.append("\n\t")
.append(exp.substring(pos+1, exp.length()));
}
return sb.toString();
} else {
return exp;
}
}
private void doAugments(PrintWriter writer) {
if ((exports.size() + exportsTo.size() + uses.size() + provides.size()) == 0)
return;
writer.println(" // augmented from module-info.java.extra");
exports.stream()
.sorted()
.forEach(e -> writer.format(" exports %s;%n", e));
// remaining injected qualified exports
exportsTo.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(e -> String.format(" exports %s to%n%s;", e.getKey(),
e.getValue().stream().sorted()
.map(mn -> String.format(" %s", mn))
.collect(Collectors.joining(",\n"))))
.forEach(writer::println);
uses.stream().sorted()
.forEach(s -> writer.format(" uses %s;%n", s));
provides.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.flatMap(e -> e.getValue().stream().sorted()
.map(impl -> String.format(" provides %s with %s;",
e.getKey(), impl)))
.forEach(writer::println);
}
}

View File

@ -1,280 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package build.tools.module;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Module {
public static class Dependence implements Comparable<Dependence> {
final String name;
final boolean reexport;
Dependence(String name) {
this(name, false);
}
Dependence(String name, boolean reexport) {
this.name = name;
this.reexport = reexport;
}
public String name() {
return name;
}
public boolean reexport(){
return reexport;
}
@Override
public int hashCode() {
int hash = 5;
hash = 11 * hash + Objects.hashCode(this.name);
hash = 11 * hash + (this.reexport ? 1 : 0);
return hash;
}
public boolean equals(Object o) {
Dependence d = (Dependence)o;
return this.name.equals(d.name) && this.reexport == d.reexport;
}
@Override
public int compareTo(Dependence o) {
int rc = this.name.compareTo(o.name);
return rc != 0 ? rc : Boolean.compare(this.reexport, o.reexport);
}
@Override
public String toString() {
return String.format("requires %s%s;",
reexport ? "public " : "", name);
}
}
private final String moduleName;
private final Set<Dependence> requires;
private final Map<String, Set<String>> exports;
private final Set<String> uses;
private final Map<String, Set<String>> provides;
private Module(String name,
Set<Dependence> requires,
Map<String, Set<String>> exports,
Set<String> uses,
Map<String, Set<String>> provides) {
this.moduleName = name;
this.requires = Collections.unmodifiableSet(requires);
this.exports = Collections.unmodifiableMap(exports);
this.uses = Collections.unmodifiableSet(uses);
this.provides = Collections.unmodifiableMap(provides);
}
public String name() {
return moduleName;
}
public Set<Dependence> requires() {
return requires;
}
public Map<String, Set<String>> exports() {
return exports;
}
public Set<String> uses() {
return uses;
}
public Map<String, Set<String>> provides() {
return provides;
}
@Override
public boolean equals(Object ob) {
if (!(ob instanceof Module)) {
return false;
}
Module that = (Module) ob;
return (moduleName.equals(that.moduleName)
&& requires.equals(that.requires)
&& exports.equals(that.exports));
}
@Override
public int hashCode() {
int hc = moduleName.hashCode();
hc = hc * 43 + requires.hashCode();
hc = hc * 43 + exports.hashCode();
return hc;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("module %s {%n", moduleName));
requires.stream()
.sorted()
.map(d -> String.format(" requires %s%s;%n", d.reexport ? "public " : "", d.name))
.forEach(sb::append);
exports.entrySet().stream()
.filter(e -> e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> String.format(" exports %s;%n", e.getKey()))
.forEach(sb::append);
exports.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.map(e -> String.format(" exports %s to%n%s;%n", e.getKey(),
e.getValue().stream().sorted()
.map(mn -> String.format(" %s", mn))
.collect(Collectors.joining(",\n"))))
.forEach(sb::append);
uses.stream().sorted()
.map(s -> String.format(" uses %s;%n", s))
.forEach(sb::append);
provides.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.flatMap(e -> e.getValue().stream().sorted()
.map(impl -> String.format(" provides %s with %s;%n", e.getKey(), impl)))
.forEach(sb::append);
sb.append("}").append("\n");
return sb.toString();
}
/**
* Module Builder
*/
static class Builder {
private String name;
final Set<Dependence> requires = new HashSet<>();
final Map<String, Set<String>> exports = new HashMap<>();
final Set<String> uses = new HashSet<>();
final Map<String, Set<String>> provides = new HashMap<>();
public Builder() {
}
public Builder name(String n) {
name = n;
return this;
}
public Builder require(String d, boolean reexport) {
requires.add(new Dependence(d, reexport));
return this;
}
public Builder export(String p) {
Objects.requireNonNull(p);
if (exports.containsKey(p)) {
throw new RuntimeException(name + " already exports " + p +
" " + exports.get(p));
}
return exportTo(p, Collections.emptySet());
}
public Builder exportTo(String p, String mn) {
Objects.requireNonNull(p);
Objects.requireNonNull(mn);
Set<String> ms = exports.get(p);
if (ms != null && ms.isEmpty()) {
throw new RuntimeException(name + " already has unqualified exports " + p);
}
exports.computeIfAbsent(p, _k -> new HashSet<>()).add(mn);
return this;
}
public Builder exportTo(String p, Set<String> ms) {
Objects.requireNonNull(p);
Objects.requireNonNull(ms);
if (exports.containsKey(p)) {
throw new RuntimeException(name + " already exports " + p +
" " + exports.get(p));
}
exports.put(p, new HashSet<>(ms));
return this;
}
public Builder use(String cn) {
uses.add(cn);
return this;
}
public Builder provide(String s, String impl) {
provides.computeIfAbsent(s, _k -> new HashSet<>()).add(impl);
return this;
}
public Builder merge(Module m1, Module m2) {
if (!m1.name().equals(m2.name())) {
throw new IllegalArgumentException(m1.name() + " != " + m2.name());
}
name = m1.name();
// ## reexports
requires.addAll(m1.requires());
requires.addAll(m2.requires());
Stream.concat(m1.exports().keySet().stream(), m2.exports().keySet().stream())
.distinct()
.forEach(pn -> {
Set<String> s1 = m2.exports().get(pn);
Set<String> s2 = m2.exports().get(pn);
if (s1 == null || s2 == null) {
exportTo(pn, s1 != null ? s1 : s2);
} else if (s1.isEmpty() || s2.isEmpty()) {
// unqualified exports
export(pn);
} else {
exportTo(pn, Stream.concat(s1.stream(), s2.stream())
.collect(Collectors.toSet()));
}
});
uses.addAll(m1.uses());
uses.addAll(m2.uses());
m1.provides().keySet().stream()
.forEach(s -> m1.provides().get(s).stream()
.forEach(impl -> provide(s, impl)));
m2.provides().keySet().stream()
.forEach(s -> m2.provides().get(s).stream()
.forEach(impl -> provide(s, impl)));
return this;
}
public Module build() {
Module m = new Module(name, requires, exports, uses, provides);
return m;
}
@Override
public String toString() {
return name != null ? name : "Unknown";
}
}
}

View File

@ -1,357 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package build.tools.module;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import build.tools.module.Module.Builder;
/**
* Source reader of module-info.java
*/
public class ModuleInfoReader {
private final Path sourcefile;
private final Builder builder;
private ModuleInfoReader(Path file) {
this.sourcefile = file;
this.builder = new Builder();
}
public static Builder builder(Path file) throws IOException {
ModuleInfoReader reader = new ModuleInfoReader(file);
reader.readFile();
return reader.builder;
}
/**
* Reads the source file.
*/
void readFile() throws IOException {
List<String> lines = Files.readAllLines(sourcefile);
boolean done = false;
int lineNumber = 0;
boolean inBlockComment = false;
boolean inRequires = false;
boolean reexports = false;
boolean inProvides = false;
boolean inWith = false;
String serviceIntf = null;
String providerClass = null;
boolean inUses = false;
boolean inExports = false;
boolean inExportsTo = false;
String qualifiedExports = null;
Counter counter = new Counter();
for (String line : lines) {
lineNumber++;
if (inBlockComment) {
int c = line.indexOf("*/");
if (c >= 0) {
line = line.substring(c + 2, line.length());
inBlockComment = false;
} else {
// skip lines until end of comment block
continue;
}
}
inBlockComment = beginBlockComment(line);
line = trimComment(line).trim();
// ignore empty lines
if (line.length() == 0) {
continue;
}
String values;
if (inRequires || inExports | inUses | (inWith && providerClass == null)) {
values = line;
} else {
String[] s = line.split("\\s+");
String keyword = s[0].trim();
int nextIndex = keyword.length();
switch (keyword) {
case "module":
if (s.length != 3 || !s[2].trim().equals("{")) {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed");
}
builder.name(s[1].trim());
continue; // next line
case "requires":
inRequires = true;
counter.numRequires++;
if (s.length >= 2) {
String ss = s[1].trim();
if (ss.equals("public")) {
nextIndex = line.indexOf(ss) + ss.length();
reexports = true;
}
}
break;
case "exports":
inExports = true;
inExportsTo = false;
counter.numExports++;
qualifiedExports = null;
if (s.length >= 3) {
qualifiedExports = s[1].trim();
nextIndex = line.indexOf(qualifiedExports, nextIndex)
+ qualifiedExports.length();
if (s[2].trim().equals("to")) {
inExportsTo = true;
nextIndex = line.indexOf("to", nextIndex) + "to".length();
} else {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed: " + s[2]);
}
}
break;
case "to":
if (!inExports || qualifiedExports == null) {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed");
}
inExportsTo = true;
break;
case "uses":
inUses = true;
counter.numUses++;
break;
case "provides":
inProvides = true;
inWith = false;
counter.numProvides++;
serviceIntf = null;
providerClass = null;
if (s.length >= 2) {
serviceIntf = s[1].trim();
nextIndex = line.indexOf(serviceIntf) + serviceIntf.length();
}
if (s.length >= 3) {
if (s[2].trim().equals("with")) {
inWith = true;
nextIndex = line.indexOf("with") + "with".length();
} else {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed: " + s[2]);
}
}
break;
case "with":
if (!inProvides || serviceIntf == null) {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed");
}
inWith = true;
nextIndex = line.indexOf("with") + "with".length();
break;
case "}":
counter.validate(builder);
done = true;
continue; // next line
default:
throw new RuntimeException(sourcefile + ", \"" +
keyword + "\" on line " +
lineNumber + ", is not recognized");
}
values = line.substring(nextIndex, line.length()).trim();
}
int len = values.length();
if (len == 0) {
continue; // next line
}
char lastchar = values.charAt(len - 1);
if (lastchar != ',' && lastchar != ';') {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", is malformed:" +
" ',' or ';' is missing.");
}
values = values.substring(0, len - 1).trim();
// parse the values specified for a keyword specified
for (String s : values.split(",")) {
s = s.trim();
if (s.length() > 0) {
if (inRequires) {
if (builder.requires.contains(s)) {
throw new RuntimeException(sourcefile + ", line "
+ lineNumber + " duplicated requires: \"" + s + "\"");
}
builder.require(s, reexports);
} else if (inExports) {
if (!inExportsTo && qualifiedExports == null) {
builder.export(s);
} else {
builder.exportTo(qualifiedExports, s);
}
} else if (inUses) {
builder.use(s);
} else if (inProvides) {
if (!inWith) {
serviceIntf = s;
} else {
providerClass = s;
builder.provide(serviceIntf, providerClass);
}
}
}
}
if (lastchar == ';') {
inRequires = false;
reexports = false;
inExports = false;
inExportsTo = false;
inProvides = false;
inWith = false;
inUses = false;
}
}
if (inBlockComment) {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", missing \"*/\" to end a block comment");
}
if (!done) {
throw new RuntimeException(sourcefile + ", line " +
lineNumber + ", missing \"}\" to end module definition" +
" for \"" + builder + "\"");
}
return;
}
// the naming convention for the module names without dashes
private static final Pattern CLASS_NAME_PATTERN = Pattern.compile("[\\w\\.\\*_$/]+");
private static boolean beginBlockComment(String line) {
int pos = 0;
while (pos >= 0 && pos < line.length()) {
int c = line.indexOf("/*", pos);
if (c < 0) {
return false;
}
if (c > 0 && !Character.isWhitespace(line.charAt(c - 1))) {
return false;
}
int c1 = line.indexOf("//", pos);
if (c1 >= 0 && c1 < c) {
return false;
}
int c2 = line.indexOf("*/", c + 2);
if (c2 < 0) {
return true;
}
pos = c + 2;
}
return false;
}
private static String trimComment(String line) {
StringBuilder sb = new StringBuilder();
int pos = 0;
while (pos >= 0 && pos < line.length()) {
int c1 = line.indexOf("//", pos);
if (c1 > 0 && !Character.isWhitespace(line.charAt(c1 - 1))) {
// not a comment
c1 = -1;
}
int c2 = line.indexOf("/*", pos);
if (c2 > 0 && !Character.isWhitespace(line.charAt(c2 - 1))) {
// not a comment
c2 = -1;
}
int c = line.length();
int n = line.length();
if (c1 >= 0 || c2 >= 0) {
if (c1 >= 0) {
c = c1;
}
if (c2 >= 0 && c2 < c) {
c = c2;
}
int c3 = line.indexOf("*/", c2 + 2);
if (c == c2 && c3 > c2) {
n = c3 + 2;
}
}
if (c > 0) {
if (sb.length() > 0) {
// add a whitespace if multiple comments on one line
sb.append(" ");
}
sb.append(line.substring(pos, c));
}
pos = n;
}
return sb.toString();
}
static class Counter {
int numRequires;
int numExports;
int numUses;
int numProvides;
void validate(Builder builder) {
assertEquals("requires", numRequires, builder.requires.size(),
() -> builder.requires.stream()
.map(Module.Dependence::toString));
assertEquals("exports", numExports, builder.exports.size(),
() -> builder.exports.entrySet().stream()
.map(e -> "exports " + e.getKey() + " to " + e.getValue()));
assertEquals("uses", numUses, builder.uses.size(),
() -> builder.uses.stream());
assertEquals("provides", numProvides,
(int)builder.provides.values().stream()
.flatMap(s -> s.stream())
.count(),
() -> builder.provides.entrySet().stream()
.map(e -> "provides " + e.getKey() + " with " + e.getValue()));
}
private static void assertEquals(String msg, int expected, int got,
Supplier<Stream<String>> supplier) {
if (expected != got){
System.err.println("ERROR: mismatched " + msg +
" expected: " + expected + " got: " + got );
supplier.get().sorted()
.forEach(System.err::println);
throw new AssertionError("mismatched " + msg +
" expected: " + expected + " got: " + got + " ");
}
}
}
}

View File

@ -1,162 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package build.tools.module;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.XMLEvent;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;
public class ModulesXmlReader {
private ModulesXmlReader() {}
public static Set<Module> readModules(Path modulesXml)
throws XMLStreamException, IOException
{
Set<Module> modules = new HashSet<>();
try (InputStream in = new BufferedInputStream(Files.newInputStream(modulesXml))) {
Set<Module> mods = ModulesXmlReader.load(in);
modules.addAll(mods);
}
return modules;
}
private static final String MODULES = "modules";
private static final String MODULE = "module";
private static final String NAME = "name";
private static final String DEPEND = "depend";
private static final String EXPORT = "export";
private static final String TO = "to";
private static final QName REEXPORTS = new QName("re-exports");
private static Set<Module> load(InputStream in)
throws XMLStreamException, IOException
{
Set<Module> modules = new HashSet<>();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader stream = factory.createXMLEventReader(in);
Module.Builder mb = null;
String modulename = null;
String pkg = null;
Set<String> permits = new HashSet<>();
while (stream.hasNext()) {
XMLEvent event = stream.nextEvent();
if (event.isStartElement()) {
String startTag = event.asStartElement().getName().getLocalPart();
switch (startTag) {
case MODULES:
break;
case MODULE:
if (mb != null) {
throw new RuntimeException("end tag for module is missing");
}
modulename = getNextTag(stream, NAME);
mb = new Module.Builder();
mb.name(modulename);
break;
case NAME:
throw new RuntimeException(event.toString());
case DEPEND:
boolean reexports = false;
Attribute attr = event.asStartElement().getAttributeByName(REEXPORTS);
if (attr != null) {
String value = attr.getValue();
if (value.equals("true") || value.equals("false")) {
reexports = Boolean.parseBoolean(value);
} else {
throw new RuntimeException("unexpected attribute " + attr.toString());
}
}
mb.require(getData(stream), reexports);
break;
case EXPORT:
pkg = getNextTag(stream, NAME);
break;
case TO:
permits.add(getData(stream));
break;
default:
}
} else if (event.isEndElement()) {
String endTag = event.asEndElement().getName().getLocalPart();
switch (endTag) {
case MODULE:
modules.add(mb.build());
mb = null;
break;
case EXPORT:
if (pkg == null) {
throw new RuntimeException("export-to is malformed");
}
mb.exportTo(pkg, permits);
pkg = null;
permits.clear();
break;
default:
}
} else if (event.isCharacters()) {
String s = event.asCharacters().getData();
if (!s.trim().isEmpty()) {
throw new RuntimeException("export-to is malformed");
}
}
}
return modules;
}
private static String getData(XMLEventReader reader)
throws XMLStreamException
{
XMLEvent e = reader.nextEvent();
if (e.isCharacters())
return e.asCharacters().getData();
throw new RuntimeException(e.toString());
}
private static String getNextTag(XMLEventReader reader, String tag)
throws XMLStreamException
{
XMLEvent e = reader.nextTag();
if (e.isStartElement()) {
String t = e.asStartElement().getName().getLocalPart();
if (!tag.equals(t)) {
throw new RuntimeException(e + " expected: " + tag);
}
return getData(reader);
}
throw new RuntimeException("export-to name is missing:" + e);
}
}

View File

@ -1,176 +0,0 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package build.tools.module;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
public final class ModulesXmlWriter {
private ModulesXmlWriter() {}
public static void writeModules(Set<Module> modules, Path path)
throws IOException, XMLStreamException
{
writeXML(modules, path);
}
private static final String MODULES = "modules";
private static final String MODULE = "module";
private static final String NAME = "name";
private static final String DEPEND = "depend";
private static final String EXPORT = "export";
private static final String TO = "to";
private static final QName REEXPORTS = new QName("re-exports");
private static void writeXML(Set<Module> modules, Path path)
throws IOException, XMLStreamException
{
XMLOutputFactory xof = XMLOutputFactory.newInstance();
try (OutputStream out = Files.newOutputStream(path)) {
int depth = 0;
XMLStreamWriter xtw = xof.createXMLStreamWriter(out, "UTF-8");
xtw.writeStartDocument("utf-8","1.0");
writeStartElement(xtw, MODULES, depth);
modules.stream()
.sorted(Comparator.comparing(Module::name))
.forEach(m -> writeModuleElement(xtw, m, depth+1));
writeEndElement(xtw, depth);
xtw.writeCharacters("\n");
xtw.writeEndDocument();
xtw.flush();
xtw.close();
}
}
private static void writeElement(XMLStreamWriter xtw,
String element,
String value,
int depth) {
try {
writeStartElement(xtw, element, depth);
xtw.writeCharacters(value);
xtw.writeEndElement();
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
private static void writeDependElement(XMLStreamWriter xtw,
Module.Dependence d,
int depth) {
try {
writeStartElement(xtw, DEPEND, depth);
if (d.reexport) {
xtw.writeAttribute("re-exports", "true");
}
xtw.writeCharacters(d.name);
xtw.writeEndElement();
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
private static void writeExportElement(XMLStreamWriter xtw,
String pkg,
int depth) {
writeExportElement(xtw, pkg, Collections.emptySet(), depth);
}
private static void writeExportElement(XMLStreamWriter xtw,
String pkg,
Set<String> permits,
int depth) {
try {
writeStartElement(xtw, EXPORT, depth);
writeElement(xtw, NAME, pkg, depth+1);
if (!permits.isEmpty()) {
permits.stream().sorted()
.forEach(m -> writeElement(xtw, TO, m, depth + 1));
}
writeEndElement(xtw, depth);
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
private static void writeModuleElement(XMLStreamWriter xtw,
Module m,
int depth) {
try {
writeStartElement(xtw, MODULE, depth);
writeElement(xtw, NAME, m.name(), depth+1);
m.requires().stream().sorted(Comparator.comparing(d -> d.name))
.forEach(d -> writeDependElement(xtw, d, depth+1));
m.exports().keySet().stream()
.filter(pn -> m.exports().get(pn).isEmpty())
.sorted()
.forEach(pn -> writeExportElement(xtw, pn, depth+1));
m.exports().entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
.sorted(Map.Entry.comparingByKey())
.forEach(e -> writeExportElement(xtw, e.getKey(), e.getValue(), depth+1));
writeEndElement(xtw, depth);
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
}
/** Two spaces; the default indentation. */
public static final String DEFAULT_INDENT = " ";
/** stack[depth] indicates what's been written into the current scope. */
private static String[] stack = new String[] { "\n",
"\n" + DEFAULT_INDENT,
"\n" + DEFAULT_INDENT + DEFAULT_INDENT,
"\n" + DEFAULT_INDENT + DEFAULT_INDENT + DEFAULT_INDENT};
private static void writeStartElement(XMLStreamWriter xtw,
String name,
int depth)
throws XMLStreamException
{
xtw.writeCharacters(stack[depth]);
xtw.writeStartElement(name);
}
private static void writeEndElement(XMLStreamWriter xtw, int depth)
throws XMLStreamException
{
xtw.writeCharacters(stack[depth]);
xtw.writeEndElement();
}
}

View File

@ -25,6 +25,7 @@
package java.lang.invoke;
import jdk.internal.loader.BootLoader;
import jdk.internal.vm.annotation.Stable;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.FieldVisitor;
@ -36,6 +37,7 @@ import java.lang.invoke.LambdaForm.NamedFunction;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
@ -463,6 +465,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
static final String SPECIES_PREFIX_NAME = "Species_";
static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
static final String SPECIES_CLASS_PREFIX = SPECIES_PREFIX_PATH.replace('/', '.');
static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
@ -489,7 +492,15 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
types, new Function<String, Class<? extends BoundMethodHandle>>() {
@Override
public Class<? extends BoundMethodHandle> apply(String types) {
return generateConcreteBMHClass(types);
String shortTypes = LambdaForm.shortenSignature(types);
String className = SPECIES_CLASS_PREFIX + shortTypes;
Class<?> c = BootLoader.loadClassOrNull(className);
if (c != null) {
return c.asSubclass(BoundMethodHandle.class);
} else {
// Not pregenerated, generate the class
return generateConcreteBMHClass(shortTypes, types);
}
}
});
}
@ -558,12 +569,49 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
* @param types the type signature, wherein reference types are erased to 'L'
* @return the generated concrete BMH class
*/
static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String shortTypes,
String types) {
final String className = speciesInternalClassName(shortTypes);
byte[] classFile = generateConcreteBMHClassBytes(shortTypes, types, className);
// load class
InvokerBytecodeGenerator.maybeDump(className, classFile);
Class<? extends BoundMethodHandle> bmhClass =
UNSAFE.defineClass(className, classFile, 0, classFile.length,
BoundMethodHandle.class.getClassLoader(), null)
.asSubclass(BoundMethodHandle.class);
return bmhClass;
}
/**
* @implNote this method is used by GenerateBMHClassesPlugin to enable
* ahead-of-time generation of BMH classes at link time. It does
* added validation since this string may be user provided.
*/
static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
for (char c : types.toCharArray()) {
if ("LIJFD".indexOf(c) < 0) {
throw new IllegalArgumentException("All characters must "
+ "correspond to a basic field type: LIJFD");
}
}
String shortTypes = LambdaForm.shortenSignature(types);
final String className = SPECIES_PREFIX_PATH + shortTypes;
final String className = speciesInternalClassName(shortTypes);
return Map.entry(className,
generateConcreteBMHClassBytes(shortTypes, types, className));
}
private static String speciesInternalClassName(String shortTypes) {
return SPECIES_PREFIX_PATH + shortTypes;
}
static byte[] generateConcreteBMHClassBytes(final String shortTypes,
final String types, final String className) {
final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC
cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
cw.visitSource(sourceFile, null);
@ -699,16 +747,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
cw.visitEnd();
// load class
final byte[] classFile = cw.toByteArray();
InvokerBytecodeGenerator.maybeDump(className, classFile);
Class<? extends BoundMethodHandle> bmhClass =
//UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
UNSAFE.defineClass(className, classFile, 0, classFile.length,
BoundMethodHandle.class.getClassLoader(), null)
.asSubclass(BoundMethodHandle.class);
return bmhClass;
return cw.toByteArray();
}
private static int typeLoadOp(char t) {

View File

@ -255,7 +255,6 @@ public final class StringConcatFactory {
*/
private static final class Recipe {
private final List<RecipeElement> elements;
private final List<RecipeElement> elementsRev;
public Recipe(String src, Object[] constants) {
List<RecipeElement> el = new ArrayList<>();
@ -294,19 +293,13 @@ public final class StringConcatFactory {
el.add(new RecipeElement(acc.toString()));
}
elements = new ArrayList<>(el);
Collections.reverse(el);
elementsRev = el;
elements = el;
}
public Collection<RecipeElement> getElements() {
public List<RecipeElement> getElements() {
return elements;
}
public Collection<RecipeElement> getElementsReversed() {
return elementsRev;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -1310,7 +1303,9 @@ public final class StringConcatFactory {
// Compose append calls. This is done in reverse because the application order is
// reverse as well.
for (RecipeElement el : recipe.getElementsReversed()) {
List<RecipeElement> elements = recipe.getElements();
for (int i = elements.size() - 1; i >= 0; i--) {
RecipeElement el = elements.get(i);
MethodHandle appender;
switch (el.getTag()) {
case CONST: {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -462,10 +462,9 @@ public abstract class AbstractList<E> extends AbstractCollection<E> implements L
* @implSpec
* This implementation returns a list that subclasses
* {@code AbstractList}. The subclass stores, in private fields, the
* offset of the subList within the backing list, the size of the subList
* (which can change over its lifetime), and the expected
* {@code modCount} value of the backing list. There are two variants
* of the subclass, one of which implements {@code RandomAccess}.
* size of the subList (which can change over its lifetime), and the
* expected {@code modCount} value of the backing list. There are two
* variants of the subclass, one of which implements {@code RandomAccess}.
* If this list implements {@code RandomAccess} the returned list will
* be an instance of the subclass that implements {@code RandomAccess}.
*
@ -493,11 +492,22 @@ public abstract class AbstractList<E> extends AbstractCollection<E> implements L
* {@code (fromIndex > toIndex)}
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size());
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
// Comparison and hashing
/**
@ -623,174 +633,199 @@ public abstract class AbstractList<E> extends AbstractCollection<E> implements L
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size();
}
}
class SubList<E> extends AbstractList<E> {
private final AbstractList<E> l;
private final int offset;
private int size;
private static class SubList<E> extends AbstractList<E> {
private final AbstractList<E> root;
private final SubList<E> parent;
private final int offset;
protected int size;
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > list.size())
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
this.modCount = l.modCount;
/**
* Constructs a sublist of an arbitrary AbstractList, which is
* not a SubList itself.
*/
public SubList(AbstractList<E> root, int fromIndex, int toIndex) {
this.root = root;
this.parent = null;
this.offset = fromIndex;
this.size = toIndex - fromIndex;
this.modCount = root.modCount;
}
/**
* Constructs a sublist of another SubList.
*/
protected SubList(SubList<E> parent, int fromIndex, int toIndex) {
this.root = parent.root;
this.parent = parent;
this.offset = parent.offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = root.modCount;
}
public E set(int index, E element) {
Objects.checkIndex(index, size);
checkForComodification();
return root.set(offset + index, element);
}
public E get(int index) {
Objects.checkIndex(index, size);
checkForComodification();
return root.get(offset + index);
}
public int size() {
checkForComodification();
return size;
}
public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
root.add(offset + index, element);
updateSizeAndModCount(1);
}
public E remove(int index) {
Objects.checkIndex(index, size);
checkForComodification();
E result = root.remove(offset + index);
updateSizeAndModCount(-1);
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
root.removeRange(offset + fromIndex, offset + toIndex);
updateSizeAndModCount(fromIndex - toIndex);
}
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
root.addAll(offset + index, c);
updateSizeAndModCount(cSize);
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(int index) {
checkForComodification();
rangeCheckForAdd(index);
return new ListIterator<E>() {
private final ListIterator<E> i =
root.listIterator(offset + index);
public boolean hasNext() {
return nextIndex() < size;
}
public E next() {
if (hasNext())
return i.next();
else
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return previousIndex() >= 0;
}
public E previous() {
if (hasPrevious())
return i.previous();
else
throw new NoSuchElementException();
}
public int nextIndex() {
return i.nextIndex() - offset;
}
public int previousIndex() {
return i.previousIndex() - offset;
}
public void remove() {
i.remove();
updateSizeAndModCount(-1);
}
public void set(E e) {
i.set(e);
}
public void add(E e) {
i.add(e);
updateSizeAndModCount(1);
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList<>(this, fromIndex, toIndex);
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
private void checkForComodification() {
if (root.modCount != this.modCount)
throw new ConcurrentModificationException();
}
private void updateSizeAndModCount(int sizeChange) {
SubList<E> slist = this;
do {
slist.size += sizeChange;
slist.modCount = root.modCount;
slist = slist.parent;
} while (slist != null);
}
}
public E set(int index, E element) {
rangeCheck(index);
checkForComodification();
return l.set(index+offset, element);
}
private static class RandomAccessSubList<E>
extends SubList<E> implements RandomAccess {
public E get(int index) {
rangeCheck(index);
checkForComodification();
return l.get(index+offset);
}
/**
* Constructs a sublist of an arbitrary AbstractList, which is
* not a RandomAccessSubList itself.
*/
RandomAccessSubList(AbstractList<E> root,
int fromIndex, int toIndex) {
super(root, fromIndex, toIndex);
}
public int size() {
checkForComodification();
return size;
}
/**
* Constructs a sublist of another RandomAccessSubList.
*/
RandomAccessSubList(RandomAccessSubList<E> parent,
int fromIndex, int toIndex) {
super(parent, fromIndex, toIndex);
}
public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
l.add(index+offset, element);
this.modCount = l.modCount;
size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = l.remove(index+offset);
this.modCount = l.modCount;
size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
l.removeRange(fromIndex+offset, toIndex+offset);
this.modCount = l.modCount;
size -= (toIndex-fromIndex);
}
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
l.addAll(offset+index, c);
this.modCount = l.modCount;
size += cSize;
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
return new ListIterator<E>() {
private final ListIterator<E> i = l.listIterator(index+offset);
public boolean hasNext() {
return nextIndex() < size;
}
public E next() {
if (hasNext())
return i.next();
else
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return previousIndex() >= 0;
}
public E previous() {
if (hasPrevious())
return i.previous();
else
throw new NoSuchElementException();
}
public int nextIndex() {
return i.nextIndex() - offset;
}
public int previousIndex() {
return i.previousIndex() - offset;
}
public void remove() {
i.remove();
SubList.this.modCount = l.modCount;
size--;
}
public void set(E e) {
i.set(e);
}
public void add(E e) {
i.add(e);
SubList.this.modCount = l.modCount;
size++;
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
return new SubList<>(this, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
private void checkForComodification() {
if (this.modCount != l.modCount)
throw new ConcurrentModificationException();
}
}
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
super(list, fromIndex, toIndex);
}
public List<E> subList(int fromIndex, int toIndex) {
return new RandomAccessSubList<>(this, fromIndex, toIndex);
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new RandomAccessSubList<>(this, fromIndex, toIndex);
}
}
}

View File

@ -432,8 +432,7 @@ public class ArrayList<E> extends AbstractList<E>
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
rangeCheck(index);
Objects.checkIndex(index, size);
return elementData(index);
}
@ -447,8 +446,7 @@ public class ArrayList<E> extends AbstractList<E>
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
rangeCheck(index);
Objects.checkIndex(index, size);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
@ -511,7 +509,7 @@ public class ArrayList<E> extends AbstractList<E>
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
rangeCheck(index);
Objects.checkIndex(index, size);
modCount++;
E oldValue = elementData(index);
@ -679,17 +677,6 @@ public class ArrayList<E> extends AbstractList<E>
size = newSize;
}
/**
* Checks if the given index is in range. If not, throws an appropriate
* runtime exception. This method does *not* check if the index is
* negative: It is always used immediately prior to an array access,
* which throws an ArrayIndexOutOfBoundsException if index is negative.
*/
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* A version of rangeCheck used by add and addAll.
*/
@ -854,8 +841,7 @@ public class ArrayList<E> extends AbstractList<E>
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
rangeCheckForAdd(index);
return new ListItr(index);
}
@ -1042,76 +1028,75 @@ public class ArrayList<E> extends AbstractList<E>
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
return new SubList<>(this, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private static class SubList<E> extends AbstractList<E> implements RandomAccess {
private final ArrayList<E> root;
private final SubList<E> parent;
private final int offset;
int size;
private int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
/**
* Constructs a sublist of an arbitrary ArrayList.
*/
public SubList(ArrayList<E> root, int fromIndex, int toIndex) {
this.root = root;
this.parent = null;
this.offset = fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
this.modCount = root.modCount;
}
public E set(int index, E e) {
rangeCheck(index);
/**
* Constructs a sublist of another SubList.
*/
private SubList(SubList<E> parent, int fromIndex, int toIndex) {
this.root = parent.root;
this.parent = parent;
this.offset = parent.offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = root.modCount;
}
public E set(int index, E element) {
Objects.checkIndex(index, size);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
E oldValue = root.elementData(offset + index);
root.elementData[offset + index] = element;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
Objects.checkIndex(index, size);
checkForComodification();
return ArrayList.this.elementData(offset + index);
return root.elementData(offset + index);
}
public int size() {
checkForComodification();
return this.size;
return size;
}
public void add(int index, E e) {
public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
root.add(offset + index, element);
updateSizeAndModCount(1);
}
public E remove(int index) {
rangeCheck(index);
Objects.checkIndex(index, size);
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
E result = root.remove(offset + index);
updateSizeAndModCount(-1);
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
root.removeRange(offset + fromIndex, offset + toIndex);
updateSizeAndModCount(fromIndex - toIndex);
}
public boolean addAll(Collection<? extends E> c) {
@ -1123,11 +1108,9 @@ public class ArrayList<E> extends AbstractList<E>
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
parent.addAll(parentOffset + index, c);
this.modCount = parent.modCount;
this.size += cSize;
root.addAll(offset + index, c);
updateSizeAndModCount(cSize);
return true;
}
@ -1135,15 +1118,14 @@ public class ArrayList<E> extends AbstractList<E>
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
public ListIterator<E> listIterator(int index) {
checkForComodification();
rangeCheckForAdd(index);
final int offset = this.offset;
return new ListIterator<E>() {
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
int expectedModCount = root.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
@ -1155,7 +1137,7 @@ public class ArrayList<E> extends AbstractList<E>
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
Object[] elementData = root.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
@ -1172,7 +1154,7 @@ public class ArrayList<E> extends AbstractList<E>
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
Object[] elementData = root.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
@ -1187,7 +1169,7 @@ public class ArrayList<E> extends AbstractList<E>
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
final Object[] elementData = root.elementData;
if (offset + i >= elementData.length) {
throw new ConcurrentModificationException();
}
@ -1216,7 +1198,7 @@ public class ArrayList<E> extends AbstractList<E>
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
expectedModCount = root.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
@ -1228,7 +1210,7 @@ public class ArrayList<E> extends AbstractList<E>
checkForComodification();
try {
ArrayList.this.set(offset + lastRet, e);
root.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
@ -1242,14 +1224,14 @@ public class ArrayList<E> extends AbstractList<E>
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
expectedModCount = root.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
if (root.modCount != expectedModCount)
throw new ConcurrentModificationException();
}
};
@ -1257,12 +1239,7 @@ public class ArrayList<E> extends AbstractList<E>
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
return new SubList<>(this, fromIndex, toIndex);
}
private void rangeCheckForAdd(int index) {
@ -1275,13 +1252,24 @@ public class ArrayList<E> extends AbstractList<E>
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
if (root.modCount != modCount)
throw new ConcurrentModificationException();
}
private void updateSizeAndModCount(int sizeChange) {
SubList<E> slist = this;
do {
slist.size += sizeChange;
slist.modCount = root.modCount;
slist = slist.parent;
} while (slist != null);
}
public Spliterator<E> spliterator() {
checkForComodification();
// ArrayListSpliterator is not used because late-binding logic
// is different here
return new Spliterator<>() {
private int index = offset; // current index, modified on advance/split
private int fence = -1; // -1 until used; then one past last index
@ -1298,8 +1286,9 @@ public class ArrayList<E> extends AbstractList<E>
public ArrayListSpliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
// ArrayListSpliterator could be used here as the source is already bound
return (lo >= mid) ? null : // divide range in half unless too small
new ArrayListSpliterator<>(ArrayList.this, lo, index = mid,
new ArrayListSpliterator<>(root, lo, index = mid,
expectedModCount);
}
@ -1308,9 +1297,9 @@ public class ArrayList<E> extends AbstractList<E>
int hi = getFence(), i = index;
if (i < hi) {
index = i + 1;
@SuppressWarnings("unchecked") E e = (E)elementData[i];
@SuppressWarnings("unchecked") E e = (E)root.elementData[i];
action.accept(e);
if (ArrayList.this.modCount != expectedModCount)
if (root.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
@ -1320,7 +1309,7 @@ public class ArrayList<E> extends AbstractList<E>
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
int i, hi, mc; // hoist accesses and checks from loop
ArrayList<E> lst = ArrayList.this;
ArrayList<E> lst = root;
Object[] a;
if ((a = lst.elementData) != null) {
if ((hi = fence) < 0) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1189,37 +1189,33 @@ public class GregorianCalendar extends Calendar {
case HOUR:
case HOUR_OF_DAY:
{
int unit = max + 1; // 12 or 24 hours
int h = internalGet(field);
int nh = (h + amount) % unit;
if (nh < 0) {
nh += unit;
int rolledValue = getRolledValue(internalGet(field), amount, min, max);
int hourOfDay = rolledValue;
if (field == HOUR && internalGet(AM_PM) == PM) {
hourOfDay += 12;
}
time += ONE_HOUR * (nh - h);
// The day might have changed, which could happen if
// the daylight saving time transition brings it to
// the next day, although it's very unlikely. But we
// have to make sure not to change the larger fields.
// Create the current date/time value to perform wall-clock-based
// roll.
CalendarDate d = calsys.getCalendarDate(time, getZone());
if (internalGet(DAY_OF_MONTH) != d.getDayOfMonth()) {
d.setDate(internalGet(YEAR),
internalGet(MONTH) + 1,
internalGet(DAY_OF_MONTH));
if (field == HOUR) {
assert (internalGet(AM_PM) == PM);
d.addHours(+12); // restore PM
d.setHours(hourOfDay);
time = calsys.getTime(d);
// If we stay on the same wall-clock time, try the next or previous hour.
if (internalGet(HOUR_OF_DAY) == d.getHours()) {
hourOfDay = getRolledValue(rolledValue, amount > 0 ? +1 : -1, min, max);
if (field == HOUR && internalGet(AM_PM) == PM) {
hourOfDay += 12;
}
d.setHours(hourOfDay);
time = calsys.getTime(d);
}
int hourOfDay = d.getHours();
internalSet(field, hourOfDay % unit);
if (field == HOUR) {
internalSet(HOUR_OF_DAY, hourOfDay);
} else {
internalSet(AM_PM, hourOfDay / 12);
internalSet(HOUR, hourOfDay % 12);
}
// Get the new hourOfDay value which might have changed due to a DST transition.
hourOfDay = d.getHours();
// Update the hour related fields
internalSet(HOUR_OF_DAY, hourOfDay);
internalSet(AM_PM, hourOfDay / 12);
internalSet(HOUR, hourOfDay % 12);
// Time zone offset and/or daylight saving might have changed.
int zoneOffset = d.getZoneOffset();

View File

@ -75,136 +75,93 @@ public enum TimeUnit {
/**
* Time unit representing one thousandth of a microsecond.
*/
NANOSECONDS {
public long toNanos(long d) { return d; }
public long toMicros(long d) { return d/(C1/C0); }
public long toMillis(long d) { return d/(C2/C0); }
public long toSeconds(long d) { return d/(C3/C0); }
public long toMinutes(long d) { return d/(C4/C0); }
public long toHours(long d) { return d/(C5/C0); }
public long toDays(long d) { return d/(C6/C0); }
public long convert(long d, TimeUnit u) { return u.toNanos(d); }
int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
},
NANOSECONDS(TimeUnit.NANO_SCALE),
/**
* Time unit representing one thousandth of a millisecond.
*/
MICROSECONDS {
public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
public long toMicros(long d) { return d; }
public long toMillis(long d) { return d/(C2/C1); }
public long toSeconds(long d) { return d/(C3/C1); }
public long toMinutes(long d) { return d/(C4/C1); }
public long toHours(long d) { return d/(C5/C1); }
public long toDays(long d) { return d/(C6/C1); }
public long convert(long d, TimeUnit u) { return u.toMicros(d); }
int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
},
MICROSECONDS(TimeUnit.MICRO_SCALE),
/**
* Time unit representing one thousandth of a second.
*/
MILLISECONDS {
public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
public long toMillis(long d) { return d; }
public long toSeconds(long d) { return d/(C3/C2); }
public long toMinutes(long d) { return d/(C4/C2); }
public long toHours(long d) { return d/(C5/C2); }
public long toDays(long d) { return d/(C6/C2); }
public long convert(long d, TimeUnit u) { return u.toMillis(d); }
int excessNanos(long d, long m) { return 0; }
},
MILLISECONDS(TimeUnit.MILLI_SCALE),
/**
* Time unit representing one second.
*/
SECONDS {
public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
public long toSeconds(long d) { return d; }
public long toMinutes(long d) { return d/(C4/C3); }
public long toHours(long d) { return d/(C5/C3); }
public long toDays(long d) { return d/(C6/C3); }
public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
int excessNanos(long d, long m) { return 0; }
},
SECONDS(TimeUnit.SECOND_SCALE),
/**
* Time unit representing sixty seconds.
* @since 1.6
*/
MINUTES {
public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
public long toMinutes(long d) { return d; }
public long toHours(long d) { return d/(C5/C4); }
public long toDays(long d) { return d/(C6/C4); }
public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
int excessNanos(long d, long m) { return 0; }
},
MINUTES(TimeUnit.MINUTE_SCALE),
/**
* Time unit representing sixty minutes.
* @since 1.6
*/
HOURS {
public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
public long toHours(long d) { return d; }
public long toDays(long d) { return d/(C6/C5); }
public long convert(long d, TimeUnit u) { return u.toHours(d); }
int excessNanos(long d, long m) { return 0; }
},
HOURS(TimeUnit.HOUR_SCALE),
/**
* Time unit representing twenty four hours.
* @since 1.6
*/
DAYS {
public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
public long toDays(long d) { return d; }
public long convert(long d, TimeUnit u) { return u.toDays(d); }
int excessNanos(long d, long m) { return 0; }
};
DAYS(TimeUnit.DAY_SCALE);
// Handy constants for conversion methods
static final long C0 = 1L;
static final long C1 = C0 * 1000L;
static final long C2 = C1 * 1000L;
static final long C3 = C2 * 1000L;
static final long C4 = C3 * 60L;
static final long C5 = C4 * 60L;
static final long C6 = C5 * 24L;
// Scales as constants
private static final long NANO_SCALE = 1L;
private static final long MICRO_SCALE = 1000L * NANO_SCALE;
private static final long MILLI_SCALE = 1000L * MICRO_SCALE;
private static final long SECOND_SCALE = 1000L * MILLI_SCALE;
private static final long MINUTE_SCALE = 60L * SECOND_SCALE;
private static final long HOUR_SCALE = 60L * MINUTE_SCALE;
private static final long DAY_SCALE = 24L * HOUR_SCALE;
static final long MAX = Long.MAX_VALUE;
/**
* Scale d by m, checking for overflow.
* This has a short name to make above code more readable.
/*
* Instances cache conversion ratios and saturation cutoffs for
* the units up through SECONDS. Other cases compute them, in
* method cvt.
*/
static long x(long d, long m, long over) {
if (d > +over) return Long.MAX_VALUE;
if (d < -over) return Long.MIN_VALUE;
return d * m;
private final long scale;
private final long maxNanos;
private final long maxMicros;
private final long maxMillis;
private final long maxSecs;
private final long microRatio;
private final int milliRatio; // fits in 32 bits
private final int secRatio; // fits in 32 bits
private TimeUnit(long s) {
this.scale = s;
this.maxNanos = Long.MAX_VALUE / s;
long ur = (s >= MICRO_SCALE) ? (s / MICRO_SCALE) : (MICRO_SCALE / s);
this.microRatio = ur;
this.maxMicros = Long.MAX_VALUE / ur;
long mr = (s >= MILLI_SCALE) ? (s / MILLI_SCALE) : (MILLI_SCALE / s);
this.milliRatio = (int)mr;
this.maxMillis = Long.MAX_VALUE / mr;
long sr = (s >= SECOND_SCALE) ? (s / SECOND_SCALE) : (SECOND_SCALE / s);
this.secRatio = (int)sr;
this.maxSecs = Long.MAX_VALUE / sr;
}
// To maintain full signature compatibility with 1.5, and to improve the
// clarity of the generated javadoc (see 6287639: Abstract methods in
// enum classes should not be listed as abstract), method convert
// etc. are not declared abstract but otherwise act as abstract methods.
/**
* General conversion utility.
*
* @param d duration
* @param dst result unit scale
* @param src source unit scale
*/
private static long cvt(long d, long dst, long src) {
long r, m;
if (src == dst)
return d;
else if (src < dst)
return d / (dst / src);
else if (d > (m = Long.MAX_VALUE / (r = src / dst)))
return Long.MAX_VALUE;
else if (d < -m)
return Long.MIN_VALUE;
else
return d * r;
}
/**
* Converts the given time duration in the given unit to this unit.
@ -221,11 +178,17 @@ public enum TimeUnit {
* @param sourceDuration the time duration in the given {@code sourceUnit}
* @param sourceUnit the unit of the {@code sourceDuration} argument
* @return the converted duration in this unit,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
*/
public long convert(long sourceDuration, TimeUnit sourceUnit) {
throw new AbstractMethodError();
switch (this) {
case NANOSECONDS: return sourceUnit.toNanos(sourceDuration);
case MICROSECONDS: return sourceUnit.toMicros(sourceDuration);
case MILLISECONDS: return sourceUnit.toMillis(sourceDuration);
case SECONDS: return sourceUnit.toSeconds(sourceDuration);
default: return cvt(sourceDuration, scale, sourceUnit.scale);
}
}
/**
@ -233,11 +196,19 @@ public enum TimeUnit {
* {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
* @param duration the duration
* @return the converted duration,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
*/
public long toNanos(long duration) {
throw new AbstractMethodError();
long s, m;
if ((s = scale) == NANO_SCALE)
return duration;
else if (duration > (m = maxNanos))
return Long.MAX_VALUE;
else if (duration < -m)
return Long.MIN_VALUE;
else
return duration * s;
}
/**
@ -245,11 +216,21 @@ public enum TimeUnit {
* {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.
* @param duration the duration
* @return the converted duration,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
*/
public long toMicros(long duration) {
throw new AbstractMethodError();
long s, m;
if ((s = scale) == MICRO_SCALE)
return duration;
else if (s < MICRO_SCALE)
return duration / microRatio;
else if (duration > (m = maxMicros))
return Long.MAX_VALUE;
else if (duration < -m)
return Long.MIN_VALUE;
else
return duration * microRatio;
}
/**
@ -257,11 +238,21 @@ public enum TimeUnit {
* {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.
* @param duration the duration
* @return the converted duration,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
*/
public long toMillis(long duration) {
throw new AbstractMethodError();
long s, m;
if ((s = scale) == MILLI_SCALE)
return duration;
else if (s < MILLI_SCALE)
return duration / milliRatio;
else if (duration > (m = maxMillis))
return Long.MAX_VALUE;
else if (duration < -m)
return Long.MIN_VALUE;
else
return duration * milliRatio;
}
/**
@ -269,11 +260,21 @@ public enum TimeUnit {
* {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}.
* @param duration the duration
* @return the converted duration,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
*/
public long toSeconds(long duration) {
throw new AbstractMethodError();
long s, m;
if ((s = scale) == SECOND_SCALE)
return duration;
else if (s < SECOND_SCALE)
return duration / secRatio;
else if (duration > (m = maxSecs))
return Long.MAX_VALUE;
else if (duration < -m)
return Long.MIN_VALUE;
else
return duration * secRatio;
}
/**
@ -281,12 +282,12 @@ public enum TimeUnit {
* {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}.
* @param duration the duration
* @return the converted duration,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
* @since 1.6
*/
public long toMinutes(long duration) {
throw new AbstractMethodError();
return cvt(duration, MINUTE_SCALE, scale);
}
/**
@ -294,12 +295,12 @@ public enum TimeUnit {
* {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}.
* @param duration the duration
* @return the converted duration,
* or {@code Long.MIN_VALUE} if conversion would negatively
* overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
* or {@code Long.MAX_VALUE} if it would positively overflow.
* @since 1.6
*/
public long toHours(long duration) {
throw new AbstractMethodError();
return cvt(duration, HOUR_SCALE, scale);
}
/**
@ -310,7 +311,7 @@ public enum TimeUnit {
* @since 1.6
*/
public long toDays(long duration) {
throw new AbstractMethodError();
return cvt(duration, DAY_SCALE, scale);
}
/**
@ -320,7 +321,15 @@ public enum TimeUnit {
* @param m the number of milliseconds
* @return the number of nanoseconds
*/
abstract int excessNanos(long d, long m);
private int excessNanos(long d, long m) {
long s;
if ((s = scale) == NANO_SCALE)
return (int)(d - (m * MILLI_SCALE));
else if (s == MICRO_SCALE)
return (int)((d * 1000L) - (m * MILLI_SCALE));
else
return 0;
}
/**
* Performs a timed {@link Object#wait(long, int) Object.wait}

View File

@ -28,7 +28,6 @@ package java.util.jar;
import java.io.*;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@ -38,11 +37,10 @@ import java.security.cert.Certificate;
import java.security.AccessController;
import java.security.CodeSource;
import jdk.internal.misc.SharedSecrets;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.security.util.SignatureFileVerifier;
import static java.util.jar.Attributes.Name.MULTI_RELEASE;
/**
* The {@code JarFile} class is used to read the contents of a jar file
* from any file that can be opened with {@code java.io.RandomAccessFile}.
@ -144,8 +142,9 @@ class JarFile extends ZipFile {
private final int version;
private boolean notVersioned;
private final boolean runtimeVersioned;
private boolean isMultiRelease; // is jar multi-release?
// indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true)
// indicates if Class-Path attribute present
private boolean hasClassPathAttribute;
// true if manifest checked for special attributes
private volatile boolean hasCheckedSpecialAttributes;
@ -155,24 +154,18 @@ class JarFile extends ZipFile {
SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
BASE_VERSION = 8; // one less than lowest version for versioned entries
RUNTIME_VERSION = AccessController.doPrivileged(
new PrivilegedAction<Integer>() {
public Integer run() {
Integer v = jdk.Version.current().major();
Integer i = Integer.getInteger("jdk.util.jar.version", v);
i = i < 0 ? 0 : i;
return i > v ? v : i;
}
}
);
String multi_release = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return System.getProperty("jdk.util.jar.enableMultiRelease", "true");
}
}
);
switch (multi_release) {
int runtimeVersion = jdk.Version.current().major();
String jarVersion = AccessController.doPrivileged(
new GetPropertyAction("jdk.util.jar.version"));
if (jarVersion != null) {
int jarVer = Integer.parseInt(jarVersion);
runtimeVersion = (jarVer > runtimeVersion)
? runtimeVersion : Math.max(jarVer, 0);
}
RUNTIME_VERSION = runtimeVersion;
String enableMultiRelease = AccessController.doPrivileged(
new GetPropertyAction("jdk.util.jar.enableMultiRelease", "true"));
switch (enableMultiRelease) {
case "true":
default:
MULTI_RELEASE_ENABLED = true;
@ -353,8 +346,14 @@ class JarFile extends ZipFile {
Objects.requireNonNull(version);
this.verify = verify;
// version applies to multi-release jar files, ignored for regular jar files
this.version = MULTI_RELEASE_FORCED ? RUNTIME_VERSION : version.value();
if (MULTI_RELEASE_FORCED) {
this.version = RUNTIME_VERSION;
version = Release.RUNTIME;
} else {
this.version = version.value();
}
this.runtimeVersioned = version == Release.RUNTIME;
assert runtimeVersionExists();
}
@ -392,35 +391,18 @@ class JarFile extends ZipFile {
* @since 9
*/
public final boolean isMultiRelease() {
// do not call this code in a constructor because some subclasses use
// lazy loading of manifest so it won't be available at construction time
if (MULTI_RELEASE_ENABLED) {
// Doubled-checked locking pattern
Boolean result = isMultiRelease;
if (result == null) {
synchronized (this) {
result = isMultiRelease;
if (result == null) {
Manifest man = null;
try {
man = getManifest();
} catch (IOException e) {
//Ignored, manifest cannot be read
}
isMultiRelease = result = (man != null)
&& man.getMainAttributes().containsKey(MULTI_RELEASE)
? Boolean.TRUE : Boolean.FALSE;
}
}
}
return result == Boolean.TRUE;
} else {
return false;
if (isMultiRelease) {
return true;
}
if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
try {
checkForSpecialAttributes();
} catch (IOException io) {
isMultiRelease = false;
}
}
return isMultiRelease;
}
// the following field, isMultiRelease, should only be used in the method
// isMultiRelease(), like a static local
private volatile Boolean isMultiRelease; // is jar multi-release?
/**
* Returns the jar file manifest, or {@code null} if none.
@ -905,26 +887,44 @@ class JarFile extends ZipFile {
}
// Statics for hand-coded Boyer-Moore search
private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'};
// The bad character shift for "class-path"
private static final int[] CLASSPATH_LASTOCC;
// The good suffix shift for "class-path"
private static final int[] CLASSPATH_OPTOSFT;
private static final byte[] CLASSPATH_CHARS =
{'C','L','A','S','S','-','P','A','T','H', ':', ' '};
// The bad character shift for "class-path:"
private static final byte[] CLASSPATH_LASTOCC;
private static final byte[] MULTIRELEASE_CHARS =
{'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':', ' '};
// The bad character shift for "multi-release: "
private static final byte[] MULTIRELEASE_LASTOCC;
static {
CLASSPATH_LASTOCC = new int[128];
CLASSPATH_OPTOSFT = new int[10];
CLASSPATH_LASTOCC[(int)'c'] = 1;
CLASSPATH_LASTOCC[(int)'l'] = 2;
CLASSPATH_LASTOCC[(int)'s'] = 5;
CLASSPATH_LASTOCC[(int)'-'] = 6;
CLASSPATH_LASTOCC[(int)'p'] = 7;
CLASSPATH_LASTOCC[(int)'a'] = 8;
CLASSPATH_LASTOCC[(int)'t'] = 9;
CLASSPATH_LASTOCC[(int)'h'] = 10;
for (int i=0; i<9; i++)
CLASSPATH_OPTOSFT[i] = 10;
CLASSPATH_OPTOSFT[9]=1;
CLASSPATH_LASTOCC = new byte[64];
CLASSPATH_LASTOCC[(int)'C' - 32] = 1;
CLASSPATH_LASTOCC[(int)'L' - 32] = 2;
CLASSPATH_LASTOCC[(int)'S' - 32] = 5;
CLASSPATH_LASTOCC[(int)'-' - 32] = 6;
CLASSPATH_LASTOCC[(int)'P' - 32] = 7;
CLASSPATH_LASTOCC[(int)'A' - 32] = 8;
CLASSPATH_LASTOCC[(int)'T' - 32] = 9;
CLASSPATH_LASTOCC[(int)'H' - 32] = 10;
CLASSPATH_LASTOCC[(int)':' - 32] = 11;
CLASSPATH_LASTOCC[(int)' ' - 32] = 12;
MULTIRELEASE_LASTOCC = new byte[64];
MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1;
MULTIRELEASE_LASTOCC[(int)'U' - 32] = 2;
MULTIRELEASE_LASTOCC[(int)'T' - 32] = 4;
MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5;
MULTIRELEASE_LASTOCC[(int)'-' - 32] = 6;
MULTIRELEASE_LASTOCC[(int)'R' - 32] = 7;
MULTIRELEASE_LASTOCC[(int)'L' - 32] = 9;
MULTIRELEASE_LASTOCC[(int)'A' - 32] = 11;
MULTIRELEASE_LASTOCC[(int)'S' - 32] = 12;
MULTIRELEASE_LASTOCC[(int)'E' - 32] = 13;
MULTIRELEASE_LASTOCC[(int)':' - 32] = 14;
MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15;
}
private JarEntry getManEntry() {
@ -962,22 +962,33 @@ class JarFile extends ZipFile {
/**
* Returns true if the pattern {@code src} is found in {@code b}.
* The {@code lastOcc} and {@code optoSft} arrays are the precomputed
* bad character and good suffix shifts.
* The {@code lastOcc} array is the precomputed bad character shifts.
* Since there are no repeated substring in our search strings,
* the good suffix shifts can be replaced with a comparison.
*/
private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) {
private boolean match(byte[] src, byte[] b, byte[] lastOcc) {
int len = src.length;
int last = b.length - len;
int i = 0;
next:
while (i<=last) {
for (int j=(len-1); j>=0; j--) {
char c = (char) b[i+j];
c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c;
if (c != src[j]) {
i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]);
while (i <= last) {
for (int j = (len - 1); j >= 0; j--) {
byte c = b[i + j];
if (c >= ' ' && c <= 'z') {
if (c >= 'a') c -= 32; // Canonicalize
if (c != src[j]) {
// no match
int goodShift = (j < len - 1) ? len : 1;
int badShift = lastOcc[c - 32];
i += Math.max(j + 1 - badShift, goodShift);
continue next;
}
} else {
// no match, character not valid for name
i += len;
continue next;
}
}
}
return true;
}
@ -986,17 +997,29 @@ class JarFile extends ZipFile {
/**
* On first invocation, check if the JAR file has the Class-Path
* attribute. A no-op on subsequent calls.
* and the Multi-Release attribute. A no-op on subsequent calls.
*/
private void checkForSpecialAttributes() throws IOException {
if (hasCheckedSpecialAttributes) return;
JarEntry manEntry = getManEntry();
if (manEntry != null) {
byte[] b = getBytes(manEntry);
if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
hasClassPathAttribute = true;
if (hasCheckedSpecialAttributes) {
return;
}
synchronized (this) {
if (hasCheckedSpecialAttributes) {
return;
}
JarEntry manEntry = getManEntry();
if (manEntry != null) {
byte[] b = getBytes(manEntry);
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
CLASSPATH_LASTOCC);
// is this a multi-release jar file
if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
isMultiRelease = match(MULTIRELEASE_CHARS, b,
MULTIRELEASE_LASTOCC);
}
}
hasCheckedSpecialAttributes = true;
}
hasCheckedSpecialAttributes = true;
}
private synchronized void ensureInitialization() {

View File

@ -28,7 +28,7 @@ package java.util.jar;
import java.util.zip.*;
import java.io.*;
import sun.security.util.ManifestEntryVerifier;
import sun.misc.JarIndex;
import jdk.internal.util.jar.JarIndex;
/**
* The <code>JarInputStream</code> class is used to read the contents of

View File

@ -32,7 +32,7 @@ import java.security.*;
import java.security.cert.CertificateException;
import java.util.zip.ZipEntry;
import sun.misc.JarIndex;
import jdk.internal.util.jar.JarIndex;
import sun.security.util.ManifestDigester;
import sun.security.util.ManifestEntryVerifier;
import sun.security.util.SignatureFileVerifier;

View File

@ -65,8 +65,8 @@ import java.util.zip.ZipFile;
import jdk.internal.misc.JavaUtilZipFileAccess;
import jdk.internal.misc.SharedSecrets;
import sun.misc.InvalidJarIndexException;
import sun.misc.JarIndex;
import jdk.internal.util.jar.InvalidJarIndexError;
import jdk.internal.util.jar.JarIndex;
import sun.net.util.URLUtil;
import sun.net.www.ParseUtil;
@ -902,7 +902,7 @@ public class URLClassPath {
*/
if (!newLoader.validIndex(name)) {
/* the mapping is wrong */
throw new InvalidJarIndexException("Invalid index");
throw new InvalidJarIndexError("Invalid index");
}
}

View File

@ -23,38 +23,32 @@
* questions.
*/
package sun.misc;
import java.lang.LinkageError;
package jdk.internal.util.jar;
/**
* Thrown if the URLClassLoader finds the INDEX.LIST file of
* a jar file contains incorrect information.
*
* @author Zhenghua Li
* @since 1.3
* @since 9
*/
public
class InvalidJarIndexException extends RuntimeException {
public class InvalidJarIndexError extends Error {
static final long serialVersionUID = -6159797516569680148L;
static final long serialVersionUID = 0L;
/**
* Constructs an <code>InvalidJarIndexException</code> with no
* detail message.
* Constructs an {@code InvalidJarIndexError} with no detail message.
*/
public InvalidJarIndexException() {
public InvalidJarIndexError() {
super();
}
/**
* Constructs an <code>InvalidJarIndexException</code> with the
* specified detail message.
* Constructs an {@code InvalidJarIndexError} with the specified detail message.
*
* @param s the detail message.
*/
public InvalidJarIndexException(String s) {
public InvalidJarIndexError(String s) {
super(s);
}
}

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.misc;
package jdk.internal.util.jar;
import java.io.*;
import java.util.*;

View File

@ -180,6 +180,8 @@ module java.base {
jdk.jvmstat;
exports jdk.internal.ref to
java.desktop;
exports jdk.internal.util.jar to
jdk.jartool;
exports sun.net to
java.httpclient;
exports sun.net.dns to

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_de extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "ERROR: In JAR-Datei {0} wurde ein ung\u00FCltiges Versionsformat verwendet. Pr\u00FCfen Sie in der Dokumentation, welches Versionsformat unterst\u00FCtzt wird." },
{ "optpkg.attributeerror", "ERROR: In JAR-Datei {1} ist das erforderliche JAR-Manifestattribut {0} nicht festgelegt." },
{ "optpkg.attributeserror", "ERROR: In JAR-Datei {0} sind einige erforderliche JAR-Manifestattribute nicht festgelegt." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_es extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "ERROR: el formato del archivo JAR {0} pertenece a una versi\u00F3n no v\u00E1lida. Busque en la documentaci\u00F3n el formato de una versi\u00F3n soportada." },
{ "optpkg.attributeerror", "ERROR: el atributo obligatorio JAR manifest {0} no est\u00E1 definido en el archivo JAR {1}." },
{ "optpkg.attributeserror", "ERROR: algunos atributos obligatorios JAR manifest no est\u00E1n definidos en el archivo JAR {0}." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_fr extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "ERREUR\u00A0: le format de version utilis\u00E9 pour le fichier JAR {0} n''est pas valide. Pour conna\u00EEtre le format de version pris en charge, consultez la documentation." },
{ "optpkg.attributeerror", "ERREUR\u00A0: l''attribut manifest JAR {0} obligatoire n''est pas d\u00E9fini dans le fichier JAR {1}." },
{ "optpkg.attributeserror", "ERREUR\u00A0: certains attributs manifest JAR obligatoires ne sont pas d\u00E9finis dans le fichier JAR {0}." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_it extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "ERRORE: Formato versione non valido nel file JAR {0}. Verificare nella documentazione il formato della versione supportato." },
{ "optpkg.attributeerror", "ERRORE: L''attributo manifest JAR {0} richiesto non \u00E8 impostato nel file JAR {1}." },
{ "optpkg.attributeserror", "ERRORE: Alcuni attributi manifesti JAR obbligatori non sono impostati nel file JAR {0}." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_ja extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "\u30A8\u30E9\u30FC: JAR\u30D5\u30A1\u30A4\u30EB{0}\u3067\u7121\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u5F62\u5F0F\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u5F62\u5F0F\u306B\u3064\u3044\u3066\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
{ "optpkg.attributeerror", "\u30A8\u30E9\u30FC: \u5FC5\u8981\u306AJAR\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027{0}\u304CJAR\u30D5\u30A1\u30A4\u30EB{1}\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" },
{ "optpkg.attributeserror", "\u30A8\u30E9\u30FC: \u8907\u6570\u306E\u5FC5\u8981\u306AJAR\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304CJAR\u30D5\u30A1\u30A4\u30EB{0}\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_ko extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "\uC624\uB958: {0} JAR \uD30C\uC77C\uC5D0 \uBD80\uC801\uD569\uD55C \uBC84\uC804 \uD615\uC2DD\uC774 \uC0AC\uC6A9\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC124\uBA85\uC11C\uC5D0\uC11C \uC9C0\uC6D0\uB418\uB294 \uBC84\uC804 \uD615\uC2DD\uC744 \uD655\uC778\uD558\uC2ED\uC2DC\uC624." },
{ "optpkg.attributeerror", "\uC624\uB958: \uD544\uC694\uD55C {0} JAR manifest \uC18D\uC131\uC774 {1} JAR \uD30C\uC77C\uC5D0 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." },
{ "optpkg.attributeserror", "\uC624\uB958: \uD544\uC694\uD55C \uC77C\uBD80 JAR manifest \uC18D\uC131\uC774 {0} JAR \uD30C\uC77C\uC5D0 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_pt_BR extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "ERRO: formato de vers\u00E3o inv\u00E1lido usado no arquivo JAR {0}. Verifique a documenta\u00E7\u00E3o para obter o formato de vers\u00E3o suportado." },
{ "optpkg.attributeerror", "ERRO: o atributo de manifesto JAR {0} necess\u00E1rio n\u00E3o est\u00E1 definido no arquivo JAR {1}." },
{ "optpkg.attributeserror", "ERRO: alguns atributos de manifesto JAR necess\u00E1rios n\u00E3o est\u00E3o definidos no arquivo JAR {0}." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_sv extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "FEL: Ogiltigt versionsformat i {0} JAR-fil. Kontrollera i dokumentationen vilket versionsformat som st\u00F6ds." },
{ "optpkg.attributeerror", "FEL: Obligatoriskt JAR manifest-attribut {0} \u00E4r inte inst\u00E4llt i {1} JAR-filen." },
{ "optpkg.attributeserror", "FEL: Vissa obligatoriska JAR manifest-attribut \u00E4r inte inst\u00E4llda i {0} JAR-filen." }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_zh_CN extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "\u9519\u8BEF: {0} JAR \u6587\u4EF6\u4E2D\u4F7F\u7528\u7684\u7248\u672C\u683C\u5F0F\u65E0\u6548\u3002\u8BF7\u68C0\u67E5\u6587\u6863\u4EE5\u4E86\u89E3\u652F\u6301\u7684\u7248\u672C\u683C\u5F0F\u3002" },
{ "optpkg.attributeerror", "\u9519\u8BEF: \u5FC5\u8981\u7684{0} JAR \u6E05\u5355\u5C5E\u6027\u672A\u5728{1} JAR \u6587\u4EF6\u4E2D\u8BBE\u7F6E\u3002" },
{ "optpkg.attributeserror", "\u9519\u8BEF: \u67D0\u4E9B\u5FC5\u8981\u7684 JAR \u6E05\u5355\u5C5E\u6027\u672A\u5728{0} JAR \u6587\u4EF6\u4E2D\u8BBE\u7F6E\u3002" }
};
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc.resources;
/**
* This class represents the {@code ResourceBundle}
* for sun.misc.
*
* @author Michael Colburn
*/
public class Messages_zh_TW extends java.util.ListResourceBundle {
/**
* Returns the contents of this {@code ResourceBundle}.
*
* @return the contents of this {@code ResourceBundle}.
*/
public Object[][] getContents() {
return contents;
}
private static final Object[][] contents = {
{ "optpkg.versionerror", "\u932F\u8AA4: {0} JAR \u6A94\u4F7F\u7528\u4E86\u7121\u6548\u7684\u7248\u672C\u683C\u5F0F\u3002\u8ACB\u6AA2\u67E5\u6587\u4EF6\uFF0C\u4EE5\u7372\u5F97\u652F\u63F4\u7684\u7248\u672C\u683C\u5F0F\u3002" },
{ "optpkg.attributeerror", "\u932F\u8AA4: {1} JAR \u6A94\u4E2D\u672A\u8A2D\u5B9A\u5FC5\u8981\u7684 {0} JAR \u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027\u3002" },
{ "optpkg.attributeserror", "\u932F\u8AA4: {0} JAR \u6A94\u4E2D\u672A\u8A2D\u5B9A\u67D0\u4E9B\u5FC5\u8981\u7684 JAR \u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027\u3002" }
};
}

View File

@ -197,8 +197,6 @@ public class LocaleData {
private static abstract class LocaleDataResourceBundleProvider
implements ResourceBundleProvider {
abstract protected boolean isSupportedInModule(String baseName, Locale locale);
/**
* Changes baseName to its module dependent package name and
* calls the super class implementation. For example,
@ -217,10 +215,6 @@ public class LocaleData {
* resource bundles except for the java.time supplementary data.
*/
public static abstract class CommonResourceBundleProvider extends LocaleDataResourceBundleProvider {
@Override
protected boolean isSupportedInModule(String baseName, Locale locale) {
return LocaleDataStrategy.INSTANCE.inJavaBaseModule(baseName, locale);
}
}
/**
@ -228,10 +222,6 @@ public class LocaleData {
* resource bundles for java.time.
*/
public static abstract class SupplementaryResourceBundleProvider extends LocaleDataResourceBundleProvider {
@Override
protected boolean isSupportedInModule(String baseName, Locale locale) {
return SupplementaryStrategy.INSTANCE.inJavaBaseModule(baseName, locale);
}
}
// Bundles.Strategy implementations

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -188,8 +188,10 @@ abstract class KeyStore extends KeyStoreSpi {
/*
* The keystore entries.
* Keys in the map are unique aliases (thus can differ from
* KeyEntry.getAlias())
*/
private Collection<KeyEntry> entries = new ArrayList<KeyEntry>();
private Map<String,KeyEntry> entries = new HashMap<>();
/*
* The keystore name.
@ -248,13 +250,10 @@ abstract class KeyStore extends KeyStoreSpi {
if (engineIsKeyEntry(alias) == false)
return null;
for (KeyEntry entry : entries) {
if (alias.equals(entry.getAlias())) {
return entry.getPrivateKey();
}
}
return null;
KeyEntry entry = entries.get(alias);
return (entry == null)
? null
: entry.getPrivateKey();
}
/**
@ -274,15 +273,13 @@ abstract class KeyStore extends KeyStoreSpi {
return null;
}
for (KeyEntry entry : entries) {
if (alias.equals(entry.getAlias())) {
X509Certificate[] certChain = entry.getCertificateChain();
return certChain.clone();
}
}
return null;
KeyEntry entry = entries.get(alias);
X509Certificate[] certChain = (entry == null)
? null
: entry.getCertificateChain();
return (certChain == null)
? null
: certChain.clone();
}
/**
@ -306,15 +303,13 @@ abstract class KeyStore extends KeyStoreSpi {
return null;
}
for (KeyEntry entry : entries) {
if (alias.equals(entry.getAlias()))
{
X509Certificate[] certChain = entry.getCertificateChain();
return certChain.length == 0 ? null : certChain[0];
}
}
return null;
KeyEntry entry = entries.get(alias);
X509Certificate[] certChain = (entry == null)
? null
: entry.getCertificateChain();
return (certChain == null || certChain.length == 0)
? null
: certChain[0];
}
/**
@ -378,16 +373,7 @@ abstract class KeyStore extends KeyStoreSpi {
if (key instanceof RSAPrivateCrtKey) {
KeyEntry entry = null;
boolean found = false;
for (KeyEntry e : entries) {
if (alias.equals(e.getAlias())) {
found = true;
entry = e;
break;
}
}
KeyEntry entry = entries.get(alias);
X509Certificate[] xchain;
if (chain != null) {
@ -401,11 +387,11 @@ abstract class KeyStore extends KeyStoreSpi {
xchain = null;
}
if (! found) {
if (entry == null) {
entry =
//TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
new KeyEntry(alias, null, xchain);
entries.add(entry);
storeWithUniqueAlias(alias, entry);
}
entry.setAlias(alias);
@ -484,23 +470,14 @@ abstract class KeyStore extends KeyStoreSpi {
// TODO - build CryptoAPI chain?
X509Certificate[] chain =
new X509Certificate[]{ (X509Certificate) cert };
KeyEntry entry = null;
boolean found = false;
KeyEntry entry = entries.get(alias);
for (KeyEntry e : entries) {
if (alias.equals(e.getAlias())) {
found = true;
entry = e;
break;
}
}
if (! found) {
if (entry == null) {
entry =
new KeyEntry(alias, null, chain);
entries.add(entry);
storeWithUniqueAlias(alias, entry);
}
if (entry.getPrivateKey() == null) { // trusted-cert entry
entry.setAlias(alias);
@ -532,32 +509,26 @@ abstract class KeyStore extends KeyStoreSpi {
throw new KeyStoreException("alias must not be null");
}
for (KeyEntry entry : entries) {
if (alias.equals(entry.getAlias())) {
KeyEntry entry = entries.remove(alias);
if (entry != null) {
// Get end-entity certificate and remove from system cert store
X509Certificate[] certChain = entry.getCertificateChain();
if (certChain != null) {
// Get end-entity certificate and remove from system cert store
X509Certificate[] certChain = entry.getCertificateChain();
if (certChain != null) {
try {
try {
byte[] encoding = certChain[0].getEncoded();
removeCertificate(getName(), alias, encoding,
byte[] encoding = certChain[0].getEncoded();
removeCertificate(getName(), entry.getAlias(), encoding,
encoding.length);
} catch (CertificateException e) {
throw new KeyStoreException("Cannot remove entry: " +
e);
}
} catch (CertificateException e) {
throw new KeyStoreException("Cannot remove entry: ", e);
}
Key privateKey = entry.getPrivateKey();
if (privateKey != null) {
destroyKeyContainer(
Key.getContainerName(privateKey.getHCryptProvider()));
}
entries.remove(entry);
break;
}
Key privateKey = entry.getPrivateKey();
if (privateKey != null) {
destroyKeyContainer(
Key.getContainerName(privateKey.getHCryptProvider()));
}
}
}
@ -568,8 +539,7 @@ abstract class KeyStore extends KeyStoreSpi {
* @return enumeration of the alias names
*/
public Enumeration<String> engineAliases() {
final Iterator<KeyEntry> iter = entries.iterator();
final Iterator<String> iter = entries.keySet().iterator();
return new Enumeration<String>()
{
@ -580,8 +550,7 @@ abstract class KeyStore extends KeyStoreSpi {
public String nextElement()
{
KeyEntry entry = iter.next();
return entry.getAlias();
return iter.next();
}
};
}
@ -594,15 +563,7 @@ abstract class KeyStore extends KeyStoreSpi {
* @return true if the alias exists, false otherwise
*/
public boolean engineContainsAlias(String alias) {
for (Enumeration<String> enumerator = engineAliases();
enumerator.hasMoreElements();)
{
String a = enumerator.nextElement();
if (a.equals(alias))
return true;
}
return false;
return entries.containsKey(alias);
}
/**
@ -627,13 +588,8 @@ abstract class KeyStore extends KeyStoreSpi {
return false;
}
for (KeyEntry entry : entries) {
if (alias.equals(entry.getAlias())) {
return entry.getPrivateKey() != null;
}
}
return false;
KeyEntry entry = entries.get(alias);
return entry != null && entry.getPrivateKey() != null;
}
/**
@ -643,15 +599,14 @@ abstract class KeyStore extends KeyStoreSpi {
* @return true if the entry identified by the given alias is a
* <i>trusted certificate entry</i>, false otherwise.
*/
public boolean engineIsCertificateEntry(String alias)
{
for (KeyEntry entry : entries) {
if (alias.equals(entry.getAlias())) {
return entry.getPrivateKey() == null;
}
public boolean engineIsCertificateEntry(String alias) {
if (alias == null) {
return false;
}
return false;
KeyEntry entry = entries.get(alias);
return entry != null && entry.getPrivateKey() == null;
}
/**
@ -670,9 +625,10 @@ abstract class KeyStore extends KeyStoreSpi {
* @return the (alias) name of the first entry with matching certificate,
* or null if no such entry exists in this keystore.
*/
public String engineGetCertificateAlias(Certificate cert)
{
for (KeyEntry entry : entries) {
public String engineGetCertificateAlias(Certificate cert) {
for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) {
KeyEntry entry = mapEntry.getValue();
if (entry.certChain != null && entry.certChain[0].equals(cert)) {
return entry.getAlias();
}
@ -765,20 +721,39 @@ abstract class KeyStore extends KeyStoreSpi {
try {
// Load keys and/or certificate chains
loadKeysOrCertificateChains(getName(), entries);
loadKeysOrCertificateChains(getName());
} catch (KeyStoreException e) {
throw new IOException(e);
}
}
/**
* Stores the given entry into the map, making sure
* the alias, used as the key is unique.
* If the same alias already exists, it tries to append
* a suffix (1), (2), etc to it until it finds a unique
* value.
*/
private void storeWithUniqueAlias(String alias, KeyEntry entry) {
String uniqAlias = alias;
int uniqNum = 1;
while (true) {
if (entries.putIfAbsent(uniqAlias, entry) == null) {
break;
}
uniqAlias = alias + " (" + (uniqNum++) + ")";
}
}
/**
* Generates a certificate chain from the collection of
* certificates and stores the result into a key entry.
*/
private void generateCertificateChain(String alias,
Collection<? extends Certificate> certCollection,
Collection<KeyEntry> entries)
Collection<? extends Certificate> certCollection)
{
try
{
@ -792,10 +767,8 @@ abstract class KeyStore extends KeyStoreSpi {
certChain[i] = (X509Certificate) iter.next();
}
KeyEntry entry = new KeyEntry(alias, null, certChain);
// Add cert chain
entries.add(entry);
storeWithUniqueAlias(alias,
new KeyEntry(alias, null, certChain));
}
catch (Throwable e)
{
@ -810,8 +783,7 @@ abstract class KeyStore extends KeyStoreSpi {
*/
private void generateRSAKeyAndCertificateChain(String alias,
long hCryptProv, long hCryptKey, int keyLength,
Collection<? extends Certificate> certCollection,
Collection<KeyEntry> entries)
Collection<? extends Certificate> certCollection)
{
try
{
@ -825,11 +797,9 @@ abstract class KeyStore extends KeyStoreSpi {
certChain[i] = (X509Certificate) iter.next();
}
KeyEntry entry = new KeyEntry(alias, new RSAPrivateKey(hCryptProv,
hCryptKey, keyLength), certChain);
// Add cert chain
entries.add(entry);
storeWithUniqueAlias(alias, new KeyEntry(alias,
new RSAPrivateKey(hCryptProv, hCryptKey, keyLength),
certChain));
}
catch (Throwable e)
{
@ -886,8 +856,8 @@ abstract class KeyStore extends KeyStoreSpi {
* @param name Name of keystore.
* @param entries Collection of key/certificate.
*/
private native void loadKeysOrCertificateChains(String name,
Collection<KeyEntry> entries) throws KeyStoreException;
private native void loadKeysOrCertificateChains(String name)
throws KeyStoreException;
/**
* Stores a DER-encoded certificate into the certificate store

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -272,7 +272,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
* Signature: (Ljava/lang/String;Ljava/util/Collection;)V
*/
JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains
(JNIEnv *env, jobject obj, jstring jCertStoreName, jobject jCollections)
(JNIEnv *env, jobject obj, jstring jCertStoreName)
{
/**
* Certificate in cert store has enhanced key usage extension
@ -331,7 +331,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
// Determine method ID to generate certificate chain
jmethodID mGenCertChain = env->GetMethodID(clazzOfThis,
"generateCertificateChain",
"(Ljava/lang/String;Ljava/util/Collection;Ljava/util/Collection;)V");
"(Ljava/lang/String;Ljava/util/Collection;)V");
if (mGenCertChain == NULL) {
__leave;
}
@ -339,7 +339,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
// Determine method ID to generate RSA certificate chain
jmethodID mGenRSAKeyAndCertChain = env->GetMethodID(clazzOfThis,
"generateRSAKeyAndCertificateChain",
"(Ljava/lang/String;JJILjava/util/Collection;Ljava/util/Collection;)V");
"(Ljava/lang/String;JJILjava/util/Collection;)V");
if (mGenRSAKeyAndCertChain == NULL) {
__leave;
}
@ -366,38 +366,37 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
} else {
// Private key is available
BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey);
BOOL bGetUserKey = ::CryptGetUserKey(hCryptProv, dwKeySpec, &hUserKey);
// Skip certificate if cannot find private key
if (bGetUserKey == FALSE)
{
if (bCallerFreeProv)
::CryptReleaseContext(hCryptProv, NULL);
// Skip certificate if cannot find private key
if (bGetUserKey == FALSE)
{
if (bCallerFreeProv)
::CryptReleaseContext(hCryptProv, NULL);
continue;
}
// Set cipher mode to ECB
DWORD dwCipherMode = CRYPT_MODE_ECB;
::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL);
// If the private key is present in smart card, we may not be able to
// determine the key length by using the private key handle. However,
// since public/private key pairs must have the same length, we could
// determine the key length of the private key by using the public key
// in the certificate.
dwPublicKeyLength = ::CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
&(pCertContext->pCertInfo->SubjectPublicKeyInfo));
continue;
}
// Set cipher mode to ECB
DWORD dwCipherMode = CRYPT_MODE_ECB;
::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL);
// If the private key is present in smart card, we may not be able to
// determine the key length by using the private key handle. However,
// since public/private key pairs must have the same length, we could
// determine the key length of the private key by using the public key
// in the certificate.
dwPublicKeyLength = ::CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
&(pCertContext->pCertInfo->SubjectPublicKeyInfo));
}
PCCERT_CHAIN_CONTEXT pCertChainContext = NULL;
// Build certificate chain by using system certificate store.
// Add cert chain into collection for any key usage.
//
if (GetCertificateChain(OID_EKU_ANY, pCertContext,
&pCertChainContext))
if (GetCertificateChain(OID_EKU_ANY, pCertContext, &pCertChainContext))
{
for (unsigned int i=0; i < pCertChainContext->cChain; i++)
@ -456,26 +455,26 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh
// collection
env->CallVoidMethod(obj, mGenCertChain,
env->NewStringUTF(pszNameString),
jArrayList, jCollections);
jArrayList);
}
else
{
// Determine key type: RSA or DSA
DWORD dwData = CALG_RSA_KEYX;
DWORD dwSize = sizeof(DWORD);
::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData,
&dwSize, NULL);
// Determine key type: RSA or DSA
DWORD dwData = CALG_RSA_KEYX;
DWORD dwSize = sizeof(DWORD);
::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData,
&dwSize, NULL);
if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
{
// Generate RSA certificate chain and store into cert
// chain collection
env->CallVoidMethod(obj, mGenRSAKeyAndCertChain,
env->NewStringUTF(pszNameString),
(jlong) hCryptProv, (jlong) hUserKey,
dwPublicKeyLength, jArrayList, jCollections);
if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
{
// Generate RSA certificate chain and store into cert
// chain collection
env->CallVoidMethod(obj, mGenRSAKeyAndCertChain,
env->NewStringUTF(pszNameString),
(jlong) hCryptProv, (jlong) hUserKey,
dwPublicKeyLength, jArrayList);
}
}
}
}
// Free cert chain

View File

@ -51,8 +51,8 @@ import java.text.MessageFormat;
import jdk.internal.module.Hasher;
import jdk.internal.module.ModuleInfoExtender;
import sun.misc.JarIndex;
import static sun.misc.JarIndex.INDEX_NAME;
import jdk.internal.util.jar.JarIndex;
import static jdk.internal.util.jar.JarIndex.INDEX_NAME;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static java.util.stream.Collectors.joining;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

View File

@ -46,6 +46,7 @@ import jdk.tools.jlink.internal.Archive.Entry;
import jdk.tools.jlink.internal.Archive.Entry.EntryType;
import jdk.tools.jlink.internal.PoolImpl.CompressedModuleData;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
@ -183,6 +184,8 @@ public final class ImageFileCreator {
PoolImpl resultResources;
try {
resultResources = pluginSupport.visitResources(allContent);
} catch (PluginException pe) {
throw pe;
} catch (Exception ex) {
throw new IOException(ex);
}

View File

@ -0,0 +1,226 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.tools.jlink.internal.plugins;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
* Plugin to generate java.lang.invoke classes.
*/
public final class GenerateJLIClassesPlugin implements TransformerPlugin {
private static final String NAME = "generate-jli-classes";
private static final String BMH_PARAM = "bmh";
private static final String BMH_SPECIES_PARAM = "bmh-species";
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
private static final String BMH = "java/lang/invoke/BoundMethodHandle";
private static final Method FACTORY_METHOD;
List<String> speciesTypes;
public GenerateJLIClassesPlugin() {
}
@Override
public Set<PluginType> getType() {
return Collections.singleton(CATEGORY.TRANSFORMER);
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return DESCRIPTION;
}
@Override
public Set<STATE> getState() {
return EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL);
}
@Override
public boolean hasArguments() {
return true;
}
@Override
public String getArgumentsDescription() {
return PluginsResourceBundle.getArgument(NAME);
}
/**
* @return the default Species forms to generate.
*
* This list was derived from running a Java concatenating strings
* with -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT set
* plus a subset of octane. A better long-term solution is to define
* and run a set of quick generators and extracting this list as a
* step in the build process.
*/
public static List<String> defaultSpecies() {
return List.of("LL", "L3", "L4", "L5", "L6", "L7", "L7I",
"L7II", "L7IIL", "L8", "L9", "L10", "L11", "L11I", "L11II",
"L12", "L13", "LI", "D", "L3I", "LIL", "LLI", "LLIL",
"LILL", "I", "LLILL");
}
@Override
public void configure(Map<String, String> config) {
String mainArgument = config.get(NAME);
// Enable by default
boolean bmhEnabled = true;
if (mainArgument != null) {
Set<String> args = Arrays.stream(mainArgument.split(","))
.collect(Collectors.toSet());
if (!args.contains(BMH_PARAM)) {
bmhEnabled = false;
}
}
if (!bmhEnabled) {
speciesTypes = List.of();
} else {
String args = config.get(BMH_SPECIES_PARAM);
List<String> bmhSpecies;
if (args != null && !args.isEmpty()) {
bmhSpecies = Arrays.stream(args.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
} else {
bmhSpecies = defaultSpecies();
}
// Expand BMH species signatures
speciesTypes = bmhSpecies.stream()
.map(type -> expandSignature(type))
.collect(Collectors.toList());
// Validation check
for (String type : speciesTypes) {
for (char c : type.toCharArray()) {
if ("LIJFD".indexOf(c) < 0) {
throw new PluginException("All characters must "
+ "correspond to a basic field type: LIJFD");
}
}
}
}
}
@Override
public void visit(Pool in, Pool out) {
for (Pool.ModuleData data : in.getContent()) {
if (("/java.base/" + BMH + ".class").equals(data.getPath())) {
// Add BoundMethodHandle unchanged
out.add(data);
speciesTypes.forEach(types -> generateConcreteClass(types, data, out));
} else {
if (!out.contains(data)) {
out.add(data);
}
}
}
}
@SuppressWarnings("unchecked")
private void generateConcreteClass(String types, Pool.ModuleData data, Pool out) {
try {
// Generate class
Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>)
FACTORY_METHOD.invoke(null, types);
String className = result.getKey();
byte[] bytes = result.getValue();
// Add class to pool
Pool.ModuleData ndata = new Pool.ModuleData(data.getModule(),
"/java.base/" + className + ".class",
Pool.ModuleDataType.CLASS_OR_RESOURCE,
new ByteArrayInputStream(bytes), bytes.length);
if (!out.contains(ndata)) {
out.add(ndata);
}
} catch (Exception ex) {
throw new PluginException(ex);
}
}
static {
try {
Class<?> BMHFactory = Class.forName("java.lang.invoke.BoundMethodHandle$Factory");
Method genClassMethod = BMHFactory.getDeclaredMethod("generateConcreteBMHClassBytes",
String.class);
genClassMethod.setAccessible(true);
FACTORY_METHOD = genClassMethod;
} catch (Exception e) {
throw new PluginException(e);
}
}
// Convert LL -> LL, L3 -> LLL
private static String expandSignature(String signature) {
StringBuilder sb = new StringBuilder();
char last = 'X';
int count = 0;
for (int i = 0; i < signature.length(); i++) {
char c = signature.charAt(i);
if (c >= '0' && c <= '9') {
count *= 10;
count += (c - '0');
} else {
for (int j = 1; j < count; j++) {
sb.append(last);
}
sb.append(c);
last = c;
count = 0;
}
}
for (int j = 1; j < count; j++) {
sb.append(last);
}
return sb.toString();
}
}

View File

@ -92,6 +92,7 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
"*sun/text/resources/cldr/ext/[^\\/]+_%%.class," +
"*sun/util/resources/cldr/ext/[^\\/]+_%%.class,";
private Predicate<String> predicate;
private String userParam;
private List<Locale.LanguageRange> priorityList;
private List<Locale> available;
private List<String> filtered;
@ -155,13 +156,17 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
@Override
public void configure(Map<String, String> config) {
try {
priorityList = Arrays.stream(config.get(NAME).split(","))
.map(Locale.LanguageRange::new)
.collect(Collectors.toList());
} catch (IllegalArgumentException iae) {
throw new PluginException(iae.getLocalizedMessage());
}
userParam = config.get(NAME);
priorityList = Arrays.stream(userParam.split(","))
.map(s -> {
try {
return new Locale.LanguageRange(s);
} catch (IllegalArgumentException iae) {
throw new PluginException(String.format(
PluginsResourceBundle.getMessage(NAME + ".invalidtag"), s));
}
})
.collect(Collectors.toList());
}
@Override
@ -191,7 +196,8 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
filtered = filterLocales(available);
if (filtered.isEmpty()) {
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".nomatchinglocales"));
throw new PluginException(
String.format(PluginsResourceBundle.getMessage(NAME + ".nomatchinglocales"), userParam));
}
try {

View File

@ -20,7 +20,7 @@ Level 0: constant string sharing\n\
Level 1: ZIP\n\
Level 2: both.\n\
An optional filter can be specified to list the pattern of files to be filtered.\n\
Use ^ for negation. eg: *Exception.class,*Error.class,^/java.base/java/lang/*
Use ^ for negation. e.g.: *Exception.class,*Error.class,^/java.base/java/lang/*
compact-cp.argument=<resource paths>
@ -32,17 +32,22 @@ copy-files.argument=<List of <file path>=<image target> to copy to the image>.
copy-files.description=\
If files to copy are not absolute path, JDK home dir is used.\n\
eg: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt
e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt
exclude-files.argument=<files to exclude | files of excluded files>
exclude-files.description=\
Specify files to exclude. eg: *.diz, /java.base/native/client/*
Specify files to exclude. e.g.: *.diz, /java.base/native/client/*
exclude-resources.argument=<resources to exclude | file of excluded resources>
exclude-resources.description=\
Specify resources to exclude. eg: *.jcov, */META-INF/*
Specify resources to exclude. e.g.: *.jcov, */META-INF/*
generate-jli-classes.argument=<bmh[:bmh-species=LL,L3,...]>
generate-jli-classes.description=\
Concrete java.lang.invoke classes to generate
installed-modules.description=Fast loading of module descriptors (always enabled)
@ -51,7 +56,7 @@ onoff.argument=<on|off>
sort-resources.argument=<paths in priority order | file with resource paths>
sort-resources.description=\
Sort resources. eg: */modules-info.class,/java-base/java/lang/*
Sort resources. e.g.: */modules-info.class,/java-base/java/lang/*
strip-debug.description=\
Strip debug information from the output image
@ -73,13 +78,16 @@ include-locales.argument=\
include-locales.description=\
BCP 47 language tags separated by a comma, allowing locale matching\n\
defined in RFC 4647. eg: en,ja,*-IN
defined in RFC 4647. e.g.: en,ja,*-IN
include-locales.missingpackages=\
Missing locale data packages in jdk.localedata:\n\t
include-locales.nomatchinglocales=\
No matching locales found. Check the specified pattern.
No matching locales found for \"%s\". Check the specified pattern.
include-locales.invalidtag=\
Invalid language tag: %s
main.status.ok=Functional.

View File

@ -45,5 +45,6 @@ module jdk.jlink {
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.OptimizationPlugin;
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ExcludeVMPlugin;
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.IncludeLocalesPlugin;
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin;
provides jdk.tools.jlink.plugin.PostProcessorPlugin with jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,34 +25,33 @@
package sun.util.resources.provider;
import java.lang.reflect.Module;
import java.util.Locale;
import java.util.ResourceBundle;
import sun.util.locale.provider.ResourceBundleProviderSupport;
import sun.util.resources.LocaleData;
/**
* {@code LocaleDataProvider} in module jdk.localedata implements
* {@code LocaleDataBundleProvider} in module java.base. This class works as a
* service agent between {@code ResourceBundle.getBundle} callers in java.base
* and resource bundles in jdk.localedata.
* Service Provider for loading locale data resource bundles in jdk.localedata
* except for JavaTimeSupplementary resource bundles.
*/
public class LocaleDataProvider extends LocaleData.CommonResourceBundleProvider {
@Override
protected boolean isSupportedInModule(String baseName, Locale locale) {
// The assumption here is that there are two modules containing
// resource bundles for locale support. If resource bundles are split
// into more modules, this method will need to be changed to determine
// what locales are exactly supported.
return !super.isSupportedInModule(baseName, locale);
public ResourceBundle getBundle(String baseName, Locale locale) {
return loadResourceBundle(toBundleName(baseName, locale));
}
@Override
public ResourceBundle getBundle(String baseName, Locale locale) {
if (isSupportedInModule(baseName, locale)) {
Module module = LocaleDataProvider.class.getModule();
String bundleName = toBundleName(baseName, locale);
return ResourceBundleProviderSupport.loadResourceBundle(module, bundleName);
/**
* Utility method for loading a resource bundle in jdk.localedata.
*/
static ResourceBundle loadResourceBundle(String bundleName) {
Class<?> c = Class.forName(LocaleDataProvider.class.getModule(), bundleName);
if (c != null && ResourceBundle.class.isAssignableFrom(c)) {
try {
@SuppressWarnings("unchecked")
ResourceBundle rb = ((Class<ResourceBundle>) c).newInstance();
return rb;
} catch (InstantiationException | IllegalAccessException e) {
throw new InternalError(e);
}
}
return null;
}

View File

@ -25,33 +25,16 @@
package sun.util.resources.provider;
import java.lang.reflect.Module;
import java.util.Locale;
import java.util.ResourceBundle;
import sun.util.locale.provider.ResourceBundleProviderSupport;
import sun.util.resources.LocaleData;
/**
* {@code SupplementaryLocaleDataProvider} in module jdk.localedata implements
* {@code JavaTimeSupplementaryProvider} in module java.base. This class works as a
* service agent between {@code ResourceBundle.getBundle} callers in java.base
* and resource bundles in jdk.localedata.
* Service Provider for loading JavaTimeSupplementary resource bundles in jdk.localedata.
*/
public class SupplementaryLocaleDataProvider extends LocaleData.SupplementaryResourceBundleProvider {
@Override
protected boolean isSupportedInModule(String baseName, Locale locale) {
// The assumption here is that there are two modules containing
// resource bundles for locale support. If resource bundles are split
// into more modules, this method will need to be changed to determine
// what locales are exactly supported.
return !super.isSupportedInModule(baseName, locale);
}
@Override
public ResourceBundle getBundle(String baseName, Locale locale) {
Module module = LocaleDataProvider.class.getModule();
String bundleName = toBundleName(baseName, locale);
return ResourceBundleProviderSupport.loadResourceBundle(module, bundleName);
return LocaleDataProvider.loadResourceBundle(toBundleName(baseName, locale));
}
}

View File

@ -302,6 +302,8 @@ JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
# Set the max memory for jtreg control vm
JTREG_MEMORY_OPTION = -J-Xmx512m
JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION)
# Give tests access to JT_JAVA, see JDK-8141609
JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
# Add any extra options
JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
# Set other vm and test options

View File

@ -116,221 +116,184 @@
# jdk_beans
# 8060027
java/beans/XMLEncoder/Test4903007.java generic-all
java/beans/XMLEncoder/java_awt_GridBagLayout.java generic-all
java/beans/XMLDecoder/8028054/TestConstructorFinder.java generic-all
java/beans/XMLDecoder/8028054/TestMethodFinder.java generic-all
java/beans/XMLEncoder/Test4903007.java 8060027 generic-all
java/beans/XMLEncoder/java_awt_GridBagLayout.java 8060027 generic-all
java/beans/XMLDecoder/8028054/TestConstructorFinder.java 8060027 generic-all
java/beans/XMLDecoder/8028054/TestMethodFinder.java 8060027 generic-all
# 8132565
java/beans/Introspector/8132566/OverridePropertyInfoTest.java generic-all
java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java generic-all
java/beans/Introspector/8132566/OverridePropertyInfoTest.java 8132565 generic-all
java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 generic-all
############################################################################
# jdk_lang
# 8029891
java/lang/ClassLoader/deadlock/GetResource.java generic-all
java/lang/ClassLoader/deadlock/GetResource.java 8029891 generic-all
# 7008363
java/lang/StringCoding/CheckEncodings.sh generic-all
java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all
############################################################################
# jdk_instrument
# 8061177
java/lang/instrument/RedefineBigClass.sh generic-all
java/lang/instrument/RetransformBigClass.sh generic-all
java/lang/instrument/RedefineBigClass.sh 8061177 generic-all
java/lang/instrument/RetransformBigClass.sh 8061177 generic-all
# 8072130
java/lang/instrument/BootClassPath/BootClassPathTest.sh macosx-all
java/lang/instrument/BootClassPath/BootClassPathTest.sh 8072130 macosx-all
# 8130339
java/lang/management/MemoryMXBean/LowMemoryTest.java generic-all
java/lang/management/MemoryMXBean/LowMemoryTest.java 8130339 generic-all
############################################################################
# jdk_jmx
# 8030957
com/sun/management/OperatingSystemMXBean/GetProcessCpuLoad.java aix-all
com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java aix-all
javax/management/MBeanServer/OldMBeanServerTest.java aix-all
com/sun/management/OperatingSystemMXBean/GetProcessCpuLoad.java 8030957 aix-all
com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java 8030957 aix-all
javax/management/MBeanServer/OldMBeanServerTest.java 8030957 aix-all
# 8042215
javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java generic-all
javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java 8042215 generic-all
# 8147985
sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java generic-all
sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java 8147985 generic-all
############################################################################
# jdk_net
# 7148829
sun/net/InetAddress/nameservice/simple/CacheTest.java generic-all
sun/net/InetAddress/nameservice/simple/DefaultCaching.java generic-all
sun/net/InetAddress/nameservice/simple/CacheTest.java 7148829 generic-all
sun/net/InetAddress/nameservice/simple/DefaultCaching.java 7148829 generic-all
# 7122846
java/net/MulticastSocket/NoLoopbackPackets.java macosx-all
java/net/MulticastSocket/SetLoopbackMode.java macosx-all
java/net/MulticastSocket/NoLoopbackPackets.java 7122846 macosx-all
java/net/MulticastSocket/SetLoopbackMode.java 7122846 macosx-all
# 7145658
java/net/MulticastSocket/Test.java macosx-all
java/net/MulticastSocket/Test.java 7145658 macosx-all
# 7143960
java/net/DatagramSocket/SendDatagramToBadAddress.java macosx-all
java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all
############################################################################
# jdk_nio
# 6963118
java/nio/channels/Selector/Wakeup.java windows-all
java/nio/channels/Selector/Wakeup.java 6963118 windows-all
# 7141822
java/nio/channels/DatagramChannel/ChangingAddress.java macosx-all
java/nio/channels/DatagramChannel/ChangingAddress.java 7141822 macosx-all
# 7132677
java/nio/channels/Selector/OutOfBand.java macosx-all
java/nio/channels/Selector/OutOfBand.java 7132677 macosx-all
# 7158947, Solaris 11
java/nio/file/WatchService/Basic.java solaris-all
java/nio/file/WatchService/MayFlies.java solaris-all
java/nio/file/WatchService/LotsOfEvents.java solaris-all
java/nio/file/WatchService/Basic.java 7158947 solaris-all Solaris 11
java/nio/file/WatchService/MayFlies.java 7158947 solaris-all Solaris 11
java/nio/file/WatchService/LotsOfEvents.java 7158947 solaris-all Solaris 11
# 8149712
java/nio/charset/coders/BashStreams.java generic-all
java/nio/charset/coders/BashStreams.java 8149712 generic-all
############################################################################
# jdk_rmi
# 7140992
java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all
java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java 7140992 generic-all
# 7146541
java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all
java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java 7146541 linux-all
# 7191877
java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java generic-all
java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java 7191877 generic-all
# 7195095
sun/rmi/transport/proxy/EagerHttpFallback.java generic-all
sun/rmi/transport/proxy/EagerHttpFallback.java 7195095 generic-all
# 8062724
java/rmi/activation/Activatable/extLoadedImpl/ext.sh generic-all
java/rmi/activation/Activatable/extLoadedImpl/ext.sh 8062724 generic-all
# 8145980
sun/rmi/rmic/newrmic/equivalence/run.sh generic-all
sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-all
############################################################################
# jdk_security
# 7157786
sun/security/pkcs11/ec/TestKeyFactory.java generic-all
sun/security/pkcs11/ec/TestKeyFactory.java 7157786 generic-all
# 7164518: no PortUnreachableException on Mac
sun/security/krb5/auto/Unreachable.java macosx-all
sun/security/krb5/auto/Unreachable.java 7164518 macosx-all no PortUnreachableException on Mac
# 7041639: Solaris DSA keypair generation bug
java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all
sun/security/tools/keytool/standard.sh solaris-all
java/security/KeyPairGenerator/SolarisShortDSA.java 7041639 solaris-all
sun/security/tools/keytool/standard.sh 7041639 solaris-all
# 8062758
java/security/Security/ClassLoaderDeadlock/Deadlock2.sh generic-all
java/security/Security/ClassLoaderDeadlock/Deadlock2.sh 8062758 generic-all
# 8026393
sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java generic-all
sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 8026393 generic-all
# 8077138: Some PKCS11 tests fail because NSS library is not initialized
# 8023434: NSS initialization failed
sun/security/pkcs11/Cipher/ReinitCipher.java windows-all
sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java windows-all
sun/security/pkcs11/Cipher/TestRSACipher.java windows-all
sun/security/pkcs11/Cipher/TestRSACipherWrap.java windows-all
sun/security/pkcs11/Cipher/TestRawRSACipher.java windows-all
sun/security/pkcs11/Cipher/TestSymmCiphers.java windows-all
sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java windows-all
sun/security/pkcs11/KeyAgreement/TestDH.java windows-all
sun/security/pkcs11/KeyAgreement/TestInterop.java windows-all
sun/security/pkcs11/KeyAgreement/TestShort.java windows-all
sun/security/pkcs11/KeyGenerator/DESParity.java windows-all
sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java windows-all
sun/security/pkcs11/KeyPairGenerator/TestDH2048.java windows-all
sun/security/pkcs11/KeyStore/SecretKeysBasic.sh windows-all
sun/security/pkcs11/Mac/MacKAT.java windows-all
sun/security/pkcs11/Mac/MacSameTest.java windows-all
sun/security/pkcs11/Mac/ReinitMac.java windows-all
sun/security/pkcs11/MessageDigest/ByteBuffers.java windows-all
sun/security/pkcs11/MessageDigest/DigestKAT.java windows-all
sun/security/pkcs11/MessageDigest/ReinitDigest.java windows-all
sun/security/pkcs11/MessageDigest/TestCloning.java windows-all
sun/security/pkcs11/Provider/ConfigQuotedString.sh windows-all
sun/security/pkcs11/Provider/Login.sh windows-all
sun/security/pkcs11/SampleTest.java windows-all
sun/security/pkcs11/Secmod/AddPrivateKey.java windows-all
sun/security/pkcs11/Secmod/AddTrustedCert.java windows-all
sun/security/pkcs11/Secmod/Crypto.java windows-all
sun/security/pkcs11/Secmod/GetPrivateKey.java windows-all
sun/security/pkcs11/Secmod/JksSetPrivateKey.java windows-all
sun/security/pkcs11/Secmod/LoadKeystore.java windows-all
sun/security/pkcs11/SecureRandom/Basic.java windows-all
sun/security/pkcs11/SecureRandom/TestDeserialization.java windows-all
sun/security/pkcs11/Serialize/SerializeProvider.java windows-all
sun/security/pkcs11/Signature/ByteBuffers.java windows-all
sun/security/pkcs11/Signature/ReinitSignature.java windows-all
sun/security/pkcs11/Signature/TestDSA.java windows-all
sun/security/pkcs11/Signature/TestDSAKeyLength.java windows-all
sun/security/pkcs11/Signature/TestRSAKeyLength.java windows-all
sun/security/pkcs11/ec/ReadCertificates.java windows-all
sun/security/pkcs11/ec/ReadPKCS12.java windows-all
sun/security/pkcs11/ec/TestCurves.java windows-all
sun/security/pkcs11/ec/TestECDH.java windows-all
sun/security/pkcs11/ec/TestECDH2.java windows-all
sun/security/pkcs11/ec/TestECDSA.java windows-all
sun/security/pkcs11/ec/TestECDSA2.java windows-all
sun/security/pkcs11/ec/TestECGenSpec.java windows-all
sun/security/pkcs11/rsa/KeyWrap.java windows-all
sun/security/pkcs11/rsa/TestCACerts.java windows-all
sun/security/pkcs11/rsa/TestKeyFactory.java windows-all
sun/security/pkcs11/rsa/TestKeyPairGenerator.java windows-all
sun/security/pkcs11/rsa/TestSignatures.java windows-all
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java windows-all
sun/security/pkcs11/tls/TestKeyMaterial.java windows-all
sun/security/pkcs11/tls/TestLeadingZeroesP11.java windows-all
sun/security/pkcs11/tls/TestMasterSecret.java windows-all
sun/security/pkcs11/tls/TestPRF.java windows-all
sun/security/pkcs11/tls/TestPremaster.java windows-all
sun/security/pkcs11/Cipher/ReinitCipher.java 8077138,8023434 windows-all
sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java 8077138,8023434 windows-all
sun/security/pkcs11/Cipher/TestRSACipher.java 8077138,8023434 windows-all
sun/security/pkcs11/Cipher/TestRSACipherWrap.java 8077138,8023434 windows-all
sun/security/pkcs11/Cipher/TestRawRSACipher.java 8077138,8023434 windows-all
sun/security/pkcs11/Cipher/TestSymmCiphers.java 8077138,8023434 windows-all
sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyAgreement/TestDH.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyAgreement/TestInterop.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyAgreement/TestShort.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyGenerator/DESParity.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyPairGenerator/TestDH2048.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyStore/SecretKeysBasic.sh 8077138,8023434 windows-all
sun/security/pkcs11/Mac/MacKAT.java 8077138,8023434 windows-all
sun/security/pkcs11/Mac/MacSameTest.java 8077138,8023434 windows-all
sun/security/pkcs11/Mac/ReinitMac.java 8077138,8023434 windows-all
sun/security/pkcs11/MessageDigest/ByteBuffers.java 8077138,8023434 windows-all
sun/security/pkcs11/MessageDigest/DigestKAT.java 8077138,8023434 windows-all
sun/security/pkcs11/MessageDigest/ReinitDigest.java 8077138,8023434 windows-all
sun/security/pkcs11/MessageDigest/TestCloning.java 8077138,8023434 windows-all
sun/security/pkcs11/Provider/ConfigQuotedString.sh 8077138,8023434 windows-all
sun/security/pkcs11/Provider/Login.sh 8077138,8023434 windows-all
sun/security/pkcs11/SampleTest.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/AddPrivateKey.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/AddTrustedCert.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/Crypto.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/GetPrivateKey.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/JksSetPrivateKey.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/LoadKeystore.java 8077138,8023434 windows-all
sun/security/pkcs11/SecureRandom/Basic.java 8077138,8023434 windows-all
sun/security/pkcs11/SecureRandom/TestDeserialization.java 8077138,8023434 windows-all
sun/security/pkcs11/Serialize/SerializeProvider.java 8077138,8023434 windows-all
sun/security/pkcs11/Signature/ByteBuffers.java 8077138,8023434 windows-all
sun/security/pkcs11/Signature/ReinitSignature.java 8077138,8023434 windows-all
sun/security/pkcs11/Signature/TestDSA.java 8077138,8023434 windows-all
sun/security/pkcs11/Signature/TestDSAKeyLength.java 8077138,8023434 windows-all
sun/security/pkcs11/Signature/TestRSAKeyLength.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/ReadCertificates.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/ReadPKCS12.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/TestCurves.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/TestECDH.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/TestECDH2.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/TestECDSA.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/TestECDSA2.java 8077138,8023434 windows-all
sun/security/pkcs11/ec/TestECGenSpec.java 8077138,8023434 windows-all
sun/security/pkcs11/rsa/KeyWrap.java 8077138,8023434 windows-all
sun/security/pkcs11/rsa/TestCACerts.java 8077138,8023434 windows-all
sun/security/pkcs11/rsa/TestKeyFactory.java 8077138,8023434 windows-all
sun/security/pkcs11/rsa/TestKeyPairGenerator.java 8077138,8023434 windows-all
sun/security/pkcs11/rsa/TestSignatures.java 8077138,8023434 windows-all
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8077138,8023434 windows-all
sun/security/pkcs11/tls/TestKeyMaterial.java 8077138,8023434 windows-all
sun/security/pkcs11/tls/TestLeadingZeroesP11.java 8077138,8023434 windows-all
sun/security/pkcs11/tls/TestMasterSecret.java 8077138,8023434 windows-all
sun/security/pkcs11/tls/TestPRF.java 8077138,8023434 windows-all
sun/security/pkcs11/tls/TestPremaster.java 8077138,8023434 windows-all
# 8051770
sun/security/provider/SecureRandom/StrongSecureRandom.java macosx-10.10
sun/security/provider/SecureRandom/StrongSecureRandom.java 8051770 macosx-10.10
# 8074580
sun/security/pkcs11/rsa/TestKeyPairGenerator.java generic-all
sun/security/pkcs11/rsa/TestKeyPairGenerator.java 8074580 generic-all
# 8038079
sun/security/krb5/auto/HttpNegotiateServer.java generic-all
sun/security/krb5/auto/HttpNegotiateServer.java 8038079 generic-all
# 8130302
sun/security/tools/keytool/autotest.sh generic-all
sun/security/tools/keytool/autotest.sh 8130302 generic-all
############################################################################
# jdk_sound
# 8059743
javax/sound/midi/Gervill/SoftProvider/GetDevice.java generic-all
javax/sound/midi/Gervill/SoftProvider/GetDevice.java 8059743 generic-all
############################################################################
# jdk_imageio
javax/imageio/plugins/shared/CanWriteSequence.java generic-all
javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java generic-all
javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java generic-all
javax/imageio/plugins/shared/CanWriteSequence.java 8148454 generic-all
javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java 8148454 generic-all
javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java 8148454 generic-all
############################################################################
@ -348,56 +311,41 @@ javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java generic-all
# jdk_tools
# Tests take too long, on sparcs see 7143279
# also see 8059906
tools/pack200/CommandLineTests.java generic-all
tools/pack200/CommandLineTests.java 7143279,8059906 generic-all
# 8059906 fails on solaris and macosx, 8151901
tools/pack200/Pack200Test.java generic-all
tools/pack200/Pack200Test.java 8059906,8151901 generic-all
# 8152622
tools/pack200/Pack200Props.java macosx-all
tools/pack200/Pack200Props.java 8152622 macosx-all
# 8068049
tools/launcher/FXLauncherTest.java linux-all,macosx-all
tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all
############################################################################
# jdk_jdi
# 8004127
com/sun/jdi/RedefineImplementor.sh generic-all
com/sun/jdi/RedefineImplementor.sh 8004127 generic-all
# 8031555
com/sun/jdi/JdbMethodExitTest.sh generic-all
com/sun/jdi/JdbMethodExitTest.sh 8031555 generic-all
# 8043571
com/sun/jdi/RepStep.java generic-all
com/sun/jdi/RepStep.java 8043571 generic-all
# 8058616
com/sun/jdi/RedefinePop.sh generic-all
com/sun/jdi/RedefinePop.sh 8058616 generic-all
# 8068645
com/sun/jdi/CatchPatternTest.sh generic-all
com/sun/jdi/CatchPatternTest.sh 8068645 generic-all
# 8067354
com/sun/jdi/GetLocalVariables4Test.sh windows-all
com/sun/jdi/GetLocalVariables4Test.sh 8067354 windows-all
############################################################################
# jdk_util
# 8062512
java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.java generic-all
java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.java 8062512 generic-all
# 8130337
java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java generic-all
java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java 8130337 generic-all
# 8080165, 8085982
java/util/Arrays/ParallelPrefix.java generic-all
java/util/Arrays/ParallelPrefix.java 8080165,8085982 generic-all
# 8079538
java/util/BitSet/BitSetStreamTest.java generic-all
java/util/BitSet/BitSetStreamTest.java 8079538 generic-all
############################################################################
@ -407,43 +355,33 @@ java/util/BitSet/BitSetStreamTest.java generic-all
# svc_tools
# 8031482
sun/tools/jcmd/TestJcmdSanity.java windows-all
sun/tools/jcmd/TestJcmdSanity.java 8031482 windows-all
# 8072131, 8132452
sun/tools/jmap/heapconfig/JMapHeapConfigTest.java generic-all
sun/tools/jmap/heapconfig/JMapHeapConfigTest.java 8072131,8132452 generic-all
# 8046285
sun/tools/jstatd/TestJstatdExternalRegistry.java generic-all
sun/tools/jstatd/TestJstatdExternalRegistry.java 8046285 generic-all
# 6456333
sun/tools/jps/TestJpsJarRelative.java generic-all
sun/tools/jps/TestJpsJarRelative.java 6456333 generic-all
# 6734748
sun/tools/jinfo/JInfoRunningProcessFlagTest.java generic-all
sun/tools/jinfo/JInfoRunningProcessFlagTest.java 6734748 generic-all
# 8057732
sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java generic-all
sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java 8057732 generic-all
# 8059035
sun/tools/jinfo/JInfoSanityTest.java generic-all
sun/tools/jinfo/JInfoSanityTest.java 8059035 generic-all
# 8151899
demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java generic-all
demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java 8151899 generic-all
############################################################################
# jdk_other
# 8141370
com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java linux-i586,macosx-all
com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java 8141370 linux-i586,macosx-all
############################################################################
# core_tools
# 8150975
# tools/jimage/JImageTest.java linux-i586,windows-i586
tools/jimage/JImageTest.java 8150975 linux-i586,windows-i586
############################################################################

View File

@ -60,7 +60,8 @@ tier3 = \
:jdk_rmi \
:jdk_beans \
:jdk_imageio \
:jdk_sound
:jdk_sound \
:jdk_client_sanity
###############################################################################
#
@ -351,6 +352,10 @@ jdk_desktop = \
:jdk_sound \
:jdk_imageio
# SwingSet3 tests.
jdk_client_sanity = \
sanity/client/SwingSet
###############################################################################
#
# Serviceability sanity groups

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,7 @@
/*
* @test
* @bug 4417734
* @key intermittent
* @summary Test that we get a BindException in all expected combinations
*/
import java.net.*;

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8152077
* @summary Make sure that roll() with HOUR/HOUR_OF_DAY works around standard/daylight
* time transitions
*/
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import static java.util.Calendar.*;
public class Bug8152077 {
private static final TimeZone LA = TimeZone.getTimeZone("America/Los_Angeles");
private static final TimeZone BR = TimeZone.getTimeZone("America/Sao_Paulo");
private static final int[] ALLDAY_HOURS = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
};
private static final int[] AM_HOURS = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};
private static final int[] PM_HOURS = { // in 24-hour clock
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
};
private static int errors;
public static void main(String[] args) {
TimeZone initialTz = TimeZone.getDefault();
try {
testRoll(LA, new int[] { 2016, MARCH, 13 },
new int[] { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 });
testRoll(LA, new int[] { 2016, MARCH, 13 },
new int[] { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
testRoll(LA, new int[] { 2016, MARCH, 13 }, PM_HOURS);
testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, ALLDAY_HOURS);
testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, AM_HOURS);
testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, PM_HOURS);
testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, ALLDAY_HOURS);
testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, AM_HOURS);
testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, PM_HOURS);
testRoll(BR, new int[] { 2016, OCTOBER, 15 }, ALLDAY_HOURS);
testRoll(BR, new int[] { 2016, OCTOBER, 15 }, PM_HOURS);
testRoll(BR, new int[] { 2016, OCTOBER, 16 },
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 });
testRoll(BR, new int[] { 2016, OCTOBER, 16 },
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
testRoll(BR, new int[] { 2016, OCTOBER, 16 }, PM_HOURS);
} finally {
TimeZone.setDefault(initialTz);
}
if (errors > 0) {
throw new RuntimeException("Test failed");
}
}
private static void testRoll(TimeZone tz, int[] params, int[] sequence) {
TimeZone.setDefault(tz);
for (int i = 0; i < sequence.length; i++) {
testRoll(+1, params, sequence, i);
testRoll(-1, params, sequence, i);
}
}
// amount must be 1 or -1.
private static void testRoll(int amount, int[] params, int[] sequence, int startIndex) {
int year = params[0];
int month = params[1];
int dayOfMonth = params[2];
int hourOfDay = sequence[startIndex];
Calendar cal = new GregorianCalendar(year, month, dayOfMonth,
hourOfDay, 0, 0);
int ampm = cal.get(AM_PM);
int length = sequence.length;
int count = length * 2;
int field = (length > 12) ? HOUR_OF_DAY : HOUR;
System.out.printf("roll(%s, %2d) starting from %s%n",
(field == HOUR) ? "HOUR" : "HOUR_OF_DAY", amount, cal.getTime());
for (int i = 0; i < count; i++) {
int index = (amount > 0) ? (startIndex + i + 1) % length
: Math.floorMod(startIndex - i - 1, length);
int expected = sequence[index];
if (field == HOUR) {
expected %= 12;
}
cal.roll(field, amount);
int value = cal.get(field);
if (value != expected) {
System.out.println("Unexpected field value: got=" + value
+ ", expected=" + expected);
errors++;
}
if (cal.get(DAY_OF_MONTH) != dayOfMonth) {
System.out.println("DAY_OF_MONTH changed: " + dayOfMonth
+ " to " + cal.get(DAY_OF_MONTH));
}
if (field == HOUR && cal.get(AM_PM) != ampm) {
System.out.println("AM_PM changed: " + ampm + " to " + cal.get(AM_PM));
errors++;
}
}
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8079136
* @run testng NestedSubList
* @summary Accessing a nested sublist leads to StackOverflowError
*/
import java.util.AbstractList;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.fail;
public class NestedSubList {
static final int NEST_LIMIT = 65536;
@Test(dataProvider="lists")
public void testAccessToSublists(List<Integer> list, boolean modifiable) {
Class<?> cls = list.getClass();
for (int i = 0; i < NEST_LIMIT; ++i) {
list = list.subList(0, 1);
}
try {
list.get(0);
if (modifiable) {
list.remove(0);
list.add(0, 42);
}
} catch (StackOverflowError e) {
fail("failed for " + cls);
}
}
@DataProvider
public static Object[][] lists() {
final boolean MODIFIABLE = true;
final boolean NON_MODIFIABLE = false;
List<Integer> c = Arrays.asList(42);
return new Object[][] {
{c, NON_MODIFIABLE},
{new ArrayList<>(c), MODIFIABLE},
{new LinkedList<>(c), MODIFIABLE},
{new MyList(), NON_MODIFIABLE},
{new Vector<>(c), MODIFIABLE},
{Collections.singletonList(42), NON_MODIFIABLE},
{Collections.checkedList(c, Integer.class), NON_MODIFIABLE},
{Collections.checkedList(new ArrayList<>(c), Integer.class), MODIFIABLE},
{Collections.checkedList(new LinkedList<>(c), Integer.class), MODIFIABLE},
{Collections.checkedList(new Vector<>(c), Integer.class), MODIFIABLE},
{Collections.synchronizedList(c), NON_MODIFIABLE},
{Collections.synchronizedList(new ArrayList<>(c)), MODIFIABLE},
{Collections.synchronizedList(new LinkedList<>(c)), MODIFIABLE},
{Collections.synchronizedList(new Vector<>(c)), MODIFIABLE},
{Collections.unmodifiableList(c), NON_MODIFIABLE},
{Collections.unmodifiableList(new ArrayList<>(c)), NON_MODIFIABLE},
{Collections.unmodifiableList(new LinkedList<>(c)), NON_MODIFIABLE},
{Collections.unmodifiableList(new Vector<>(c)), NON_MODIFIABLE},
};
}
static class MyList extends AbstractList<Integer> {
public Integer get(int index) { return 42; }
public int size() { return 1; }
}
}

View File

@ -0,0 +1,676 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8079136
* @library /lib/testlibrary
* @build jdk.testlibrary.*
* @run testng SubList
* @summary Basic functionality of sublists
* @key randomness
*/
import java.util.AbstractList;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
import java.util.Vector;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import jdk.testlibrary.RandomFactory;
public class SubList extends org.testng.Assert {
final Random rnd = RandomFactory.getRandom();
@Test(dataProvider = "modifiable")
public void testAdd(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
Integer e = rnd.nextInt();
subList.add(e);
assertEquals(list.get(to), e);
assertEquals(subList.size(), to - from + 1);
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModAdd(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.add(42);
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodAdd(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
subList.add(42);
}
@Test(dataProvider = "modifiable")
public void testAddAtPos(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
int i = rnd.nextInt(1 + to - from);
Integer e = rnd.nextInt();
subList.add(i, e);
assertEquals(list.get(from + i), e);
assertEquals(subList.size(), to - from + 1);
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModAddAtPos(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
int i = rnd.nextInt(1 + to - from);
subList.add(i, 42);
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodAddAtPos(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
int i = rnd.nextInt(1 + to - from);
subList.add(i, 42);
}
@Test(dataProvider = "modifiable")
public void testClear(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
subList.clear();
assertTrue(subList.isEmpty());
assertEquals(subList.size(), 0);
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModClear(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.clear();
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodClear(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
subList.clear();
}
@Test(dataProvider = "all")
public void testEquals(List<Integer> list, int from, int to) {
List<Integer> subList1 = list.subList(from, to);
List<Integer> subList2 = list.subList(from, to);
assertTrue(subList1.equals(subList2));
assertEquals(subList1.hashCode(), subList2.hashCode());
for (int i = 0; i != 16; ++i) {
int from3 = rnd.nextInt(1 + list.size());
int to3 = from3 + rnd.nextInt(1 + list.size() - from3);
boolean equal = (to - from) == (to3 - from3);
for (int j = 0; j < to - from && j < to3 - from3; ++j)
equal &= list.get(from + j) == list.get(from3 + j);
List<Integer> subList3 = list.subList(from3, to3);
assertEquals(subList1.equals(subList3), equal);
}
}
// @Test(dataProvider = "modifiable",
// expectedExceptions = ConcurrentModificationException.class)
// public void testModEquals(List<Integer> list, int from, int to) {
// List<Integer> subList = list.subList(from, to);
// list.add(42);
// subList.equals(subList);
// }
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModHashCode(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.hashCode();
}
@Test(dataProvider = "all")
public void testGet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
for (int i = 0; i < to - from; ++i)
assertEquals(list.get(from + i), subList.get(i));
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModGet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.get(from);
}
@Test(dataProvider = "all")
public void testIndexOf(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
if (from < to) {
Integer e = list.get(from);
int j = subList.indexOf(e);
assertTrue(j == 0);
}
for (int i = 0; i < list.size(); ++i) {
Integer e = list.get(i);
int j = subList.indexOf(e);
if (i < from || i >= to) {
assertTrue(j == -1 || subList.get(j) == e);
} else {
assertTrue(j >= 0);
assertTrue(j <= i - from);
assertEquals(subList.get(j), e);
}
}
for (int i = 0; i < 16; ++i) {
Integer r = rnd.nextInt();
if (list.contains(r)) continue;
int j = subList.indexOf(r);
assertTrue(j == -1);
}
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModIndexOf(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.indexOf(from);
}
@Test(dataProvider = "all")
public void testIterator(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
Iterator<Integer> it = subList.iterator();
for (int i = from; i < to; ++i) {
assertTrue(it.hasNext());
assertEquals(list.get(i), it.next());
}
assertFalse(it.hasNext());
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModIteratorNext(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
Iterator<Integer> it = subList.iterator();
list.add(42);
it.next();
}
@Test(dataProvider = "modifiable")
public void testIteratorRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
Iterator<Integer> it = subList.iterator();
for (int i = from; i < to; ++i) {
assertTrue(it.hasNext());
assertEquals(list.get(from), it.next());
it.remove();
}
assertFalse(it.hasNext());
assertTrue(subList.isEmpty());
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModIteratorRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
Iterator<Integer> it = subList.iterator();
it.next();
list.add(42);
it.remove();
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodIteratorRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
Iterator<Integer> it = subList.iterator();
it.next();
it.remove();
}
@Test(dataProvider = "all")
public void testIteratorForEachRemaining(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
for (int k = 0; k < 16; ++k) {
int r = from + rnd.nextInt(1 + to - from);
Iterator<Integer> it = subList.iterator();
for (int i = from; i < to; ++i) {
assertTrue(it.hasNext());
if (i == r) {
Iterator<Integer> jt = list.listIterator(r);
it.forEachRemaining(x ->
assertTrue(jt.hasNext() && x == jt.next()));
break;
}
assertEquals(list.get(i), it.next());
}
it.forEachRemaining(x -> fail());
}
}
@Test(dataProvider = "all")
public void testLastIndexOf(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
if (from < to) {
Integer e = list.get(to - 1);
int j = subList.lastIndexOf(e);
assertTrue(j == to - from - 1);
}
for (int i = 0; i < list.size(); ++i) {
Integer e = list.get(i);
int j = subList.lastIndexOf(e);
if (i < from || i >= to) {
assertTrue(j == -1 || subList.get(j) == e);
} else {
assertTrue(j >= 0 && j >= i - from);
assertEquals(subList.get(j), e);
}
}
for (int i = 0; i < 16; ++i) {
Integer r = rnd.nextInt();
if (list.contains(r)) continue;
int j = subList.lastIndexOf(r);
assertTrue(j == -1);
}
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModLastIndexOf(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.lastIndexOf(42);
}
@Test(dataProvider = "unresizable")
public void testListIterator(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
for (int i = from; i < to; ++i) {
assertTrue(it.hasNext());
assertTrue(it.nextIndex() == i - from);
assertEquals(list.get(i), it.next());
}
assertFalse(it.hasNext());
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModListIteratorNext(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
list.add(42);
it.next();
}
@Test(dataProvider = "modifiable")
public void testListIteratorSet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
for (int i = from; i < to; ++i) {
assertTrue(it.hasNext());
assertTrue(it.nextIndex() == i - from);
assertEquals(list.get(i), it.next());
Integer e = rnd.nextInt();
it.set(e);
assertEquals(list.get(i), e);
}
assertFalse(it.hasNext());
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModListIteratorSet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
it.next();
list.add(42);
it.set(42);
}
@Test(dataProvider = "unsettable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodListIteratorSet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
it.next();
it.set(42);
}
@Test(dataProvider = "unresizable")
public void testListIteratorPrevious(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator(subList.size());
for (int i = to - 1; i >= from; --i) {
assertTrue(it.hasPrevious());
assertTrue(it.previousIndex() == i - from);
assertEquals(list.get(i), it.previous());
}
assertFalse(it.hasPrevious());
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModListIteratorPrevious(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator(to - from);
list.add(42);
it.previous();
}
@Test(dataProvider = "modifiable")
public void testListIteratorSetPrevious(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator(subList.size());
for (int i = to - 1; i >= from; --i) {
assertTrue(it.hasPrevious());
assertTrue(it.previousIndex() == i - from);
assertEquals(list.get(i), it.previous());
Integer e = rnd.nextInt();
it.set(e);
assertEquals(list.get(i), e);
}
assertFalse(it.hasPrevious());
}
@Test(dataProvider = "unsettable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodListIteratorSetPrevious(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator(to - from);
it.previous();
it.set(42);
}
@Test(dataProvider = "modifiable")
public void testListIteratorAdd(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
for (int i = 0; i < 16; ++i) {
int r = rnd.nextInt(1 + subList.size());
ListIterator<Integer> it = subList.listIterator(r);
Integer e = rnd.nextInt();
it.add(e);
assertEquals(it.previous(), e);
assertEquals(list.get(from + r), e);
}
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodListIteratorAdd(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
int r = rnd.nextInt(1 + subList.size());
ListIterator<Integer> it = subList.listIterator(r);
it.add(42);
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModListIteratorAdd(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
it.next();
list.add(42);
it.add(42);
}
@Test(dataProvider = "modifiable")
public void testListIteratorRemoveNext(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
for (int i = from; i < to; ++i) {
assertTrue(it.hasNext());
assertTrue(it.nextIndex() == 0);
assertEquals(list.get(from), it.next());
it.remove();
}
assertFalse(it.hasNext());
assertTrue(subList.isEmpty());
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodListIteratorRemoveNext(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
it.next();
it.remove();
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModListIteratorRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator();
it.next();
list.add(42);
it.remove();
}
@Test(dataProvider = "modifiable")
public void testListIteratorRemovePrevious(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator(subList.size());
for (int i = to - 1; i >= from; --i) {
assertTrue(it.hasPrevious());
assertTrue(it.previousIndex() == i - from);
assertEquals(list.get(i), it.previous());
it.remove();
}
assertFalse(it.hasPrevious());
assertTrue(subList.isEmpty());
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodListIteratorRemovePrevious(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
ListIterator<Integer> it = subList.listIterator(subList.size());
it.previous();
it.remove();
}
@Test(dataProvider = "modifiable")
public void testRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
for (int i = 0; i < 16; ++i) {
if (subList.isEmpty()) break;
int r = rnd.nextInt(subList.size());
Integer e = list.get(from + r);
assertEquals(subList.remove(r), e);
}
}
@Test(dataProvider = "unresizable",
expectedExceptions = UnsupportedOperationException.class)
public void testUnmodRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
int r = rnd.nextInt(subList.size());
subList.remove(r);
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModRemove(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.remove(0);
}
@Test(dataProvider = "modifiable")
public void testSet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
for (int i = 0; i < to - from; ++i) {
Integer e0 = list.get(from + i);
Integer e1 = rnd.nextInt();
assertEquals(subList.set(i, e1), e0);
assertEquals(list.get(from + i), e1);
}
}
@Test(dataProvider = "modifiable",
expectedExceptions = ConcurrentModificationException.class)
public void testModSet(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
list.add(42);
subList.set(0, 42);
}
@Test(dataProvider = "all")
public void testSubList(List<Integer> list, int from, int to) {
List<Integer> subList = list.subList(from, to);
for (int i = 0; i < 16 && from < to; ++i) {
int from1 = rnd.nextInt(to - from);
int to1 = from1 + 1 + rnd.nextInt(to - from - from1);
List<Integer> subSubList = subList.subList(from1, to1);
for (int j = 0; j < to1 - from1; ++j)
assertEquals(list.get(from + from1 + j), subSubList.get(j));
}
}
/**
* All kinds of lists
*/
@DataProvider
public static Object[][] all() {
Object[][] l1 = modifiable();
Object[][] l2 = unresizable();
Object[][] res = Arrays.copyOf(l1, l1.length + l2.length);
System.arraycopy(l2, 0, res, l1.length, l2.length);
return res;
}
/**
* Lists that allow any modifications: resizing and setting values
*/
@DataProvider
public static Object[][] modifiable() {
final List<Integer> c1 = Arrays.asList(42);
final List<Integer> c9 = Arrays.asList(40, 41, 42, 43, 44, 45, -1,
Integer.MIN_VALUE, 1000500);
return new Object[][] {
{new ArrayList<>(c1), 0, 1},
{new LinkedList<>(c1), 0, 1},
{new Vector<>(c1), 0, 1},
{new ArrayList<>(c1).subList(0, 1), 0, 1},
{new LinkedList<>(c1).subList(0, 1), 0, 1},
{new Vector<>(c1).subList(0, 1), 0, 1},
{Collections.checkedList(new ArrayList<>(c1), Integer.class), 0, 1},
{Collections.checkedList(new LinkedList<>(c1), Integer.class), 0, 1},
{Collections.checkedList(new Vector<>(c1), Integer.class), 0, 1},
{Collections.synchronizedList(new ArrayList<>(c1)), 0, 1},
{Collections.synchronizedList(new LinkedList<>(c1)), 0, 1},
{Collections.synchronizedList(new Vector<>(c1)), 0, 1},
{new ArrayList<>(c9), 2, 5},
{new LinkedList<>(c9), 2, 5},
{new Vector<>(c9), 2, 5},
{new ArrayList<>(c9).subList(1, 8), 1, 4},
{new LinkedList<>(c9).subList(1, 8), 1, 4},
{new Vector<>(c9).subList(1, 8), 1, 4},
{Collections.checkedList(new ArrayList<>(c9), Integer.class), 2, 5},
{Collections.checkedList(new LinkedList<>(c9), Integer.class), 2, 5},
{Collections.checkedList(new Vector<>(c9), Integer.class), 2, 5},
{Collections.synchronizedList(new ArrayList<>(c9)), 2, 5},
{Collections.synchronizedList(new LinkedList<>(c9)), 2, 5},
{Collections.synchronizedList(new Vector<>(c9)), 2, 5},
};
}
/**
* Lists that don't allow resizing, but allow setting values
*/
@DataProvider
public static Object[][] unresizable() {
final List<Integer> c1 = Arrays.asList(42);
final List<Integer> c9 = Arrays.asList(40, 41, 42, 43, 44, 45, -1,
Integer.MIN_VALUE, 1000500);
Object[][] l1 = unsettable();
Object[][] l2 = {
{c1, 0, 1},
{c1.subList(0, 1), 0, 1},
{Collections.checkedList(c1, Integer.class), 0, 1},
{Collections.synchronizedList(c1), 0, 1},
{c9, 0, 4},
{c9, 4, 6},
{c9.subList(1, 8), 1, 4},
{c9.subList(1, 8), 0, 7},
{Collections.checkedList(c9, Integer.class), 3, 6},
{Collections.synchronizedList(c9), 3, 5},
};
Object[][] res = Arrays.copyOf(l1, l1.length + l2.length);
System.arraycopy(l2, 0, res, l1.length, l2.length);
return res;
}
/**
* Lists that don't allow either resizing or setting values
*/
@DataProvider
public static Object[][] unsettable() {
final List<Integer> c1 = Arrays.asList(42);
final List<Integer> c9 = Arrays.asList(40, 41, 42, 43, 44, 45, -1,
Integer.MIN_VALUE, 1000500);
return new Object[][] {
{new MyList(1), 0, 1},
{new MyList(1).subList(0, 1), 0, 1},
{Collections.singletonList(42), 0, 1},
{Collections.singletonList(42).subList(0, 1), 0, 1},
{Collections.unmodifiableList(c1), 0, 1},
{Collections.unmodifiableList(new ArrayList<>(c1)), 0, 1},
{Collections.unmodifiableList(new LinkedList<>(c1)), 0, 1},
{Collections.unmodifiableList(new Vector<>(c1)), 0, 1},
{new MyList(9), 3, 6},
{new MyList(9).subList(2, 8), 3, 6},
{Collections.unmodifiableList(c9), 3, 6},
{Collections.unmodifiableList(new ArrayList<>(c9)), 3, 6},
{Collections.unmodifiableList(new LinkedList<>(c9)), 3, 6},
{Collections.unmodifiableList(new Vector<>(c9)), 3, 6},
};
}
static class MyList extends AbstractList<Integer> {
private int size;
MyList(int s) { size = s; }
public Integer get(int index) { return 42; }
public int size() { return size; }
}
}

View File

@ -25,6 +25,7 @@
# @test
# @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8008577
# 8010666 8013086 8013233 8013903 8015960 8028771 8054482 8062006
# 8150432
# @summary tests for "java.locale.providers" system property
# @modules java.base/sun.util.locale
# java.base/sun.util.locale.provider
@ -168,7 +169,7 @@ case "$OS" in
PARAM1=HOST
fi
;;
CYGWIN_NT-6* | Darwin )
CYGWIN_NT-6* | CYGWIN_NT-10* | Darwin )
PARAM1=HOST
;;
* )

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -154,8 +154,8 @@ public class SpliteratorTraversingAndSplittingTest {
}
void addList(Function<Collection<T>, ? extends List<T>> l) {
// @@@ If collection is instance of List then add sub-list tests
addCollection(l);
addCollection(l.andThen(list -> list.subList(0, list.size())));
}
void addMap(Function<Map<T, T>, ? extends Map<T, T>> m) {

View File

@ -0,0 +1,103 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Written by Doug Lea and Martin Buchholz with assistance from
* members of JCP JSR-166 Expert Group and released to the public
* domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
import junit.framework.Test;
import junit.framework.TestSuite;
public class TimeUnit8Test extends JSR166TestCase {
public static void main(String[] args) {
main(suite(), args);
}
public static Test suite() {
return new TestSuite(TimeUnit8Test.class);
}
/**
* tests for toChronoUnit.
*/
public void testToChronoUnit() throws Exception {
assertSame(ChronoUnit.NANOS, NANOSECONDS.toChronoUnit());
assertSame(ChronoUnit.MICROS, MICROSECONDS.toChronoUnit());
assertSame(ChronoUnit.MILLIS, MILLISECONDS.toChronoUnit());
assertSame(ChronoUnit.SECONDS, SECONDS.toChronoUnit());
assertSame(ChronoUnit.MINUTES, MINUTES.toChronoUnit());
assertSame(ChronoUnit.HOURS, HOURS.toChronoUnit());
assertSame(ChronoUnit.DAYS, DAYS.toChronoUnit());
// Every TimeUnit has a defined ChronoUnit equivalent
for (TimeUnit x : TimeUnit.values())
assertSame(x, TimeUnit.of(x.toChronoUnit()));
}
/**
* tests for TimeUnit.of(ChronoUnit).
*/
public void testTimeUnitOf() throws Exception {
assertSame(NANOSECONDS, TimeUnit.of(ChronoUnit.NANOS));
assertSame(MICROSECONDS, TimeUnit.of(ChronoUnit.MICROS));
assertSame(MILLISECONDS, TimeUnit.of(ChronoUnit.MILLIS));
assertSame(SECONDS, TimeUnit.of(ChronoUnit.SECONDS));
assertSame(MINUTES, TimeUnit.of(ChronoUnit.MINUTES));
assertSame(HOURS, TimeUnit.of(ChronoUnit.HOURS));
assertSame(DAYS, TimeUnit.of(ChronoUnit.DAYS));
assertThrows(NullPointerException.class,
() -> TimeUnit.of((ChronoUnit)null));
// ChronoUnits either round trip to their TimeUnit
// equivalents, or throw IllegalArgumentException.
for (ChronoUnit cu : ChronoUnit.values()) {
final TimeUnit tu;
try {
tu = TimeUnit.of(cu);
} catch (IllegalArgumentException acceptable) {
continue;
}
assertSame(cu, tu.toChronoUnit());
}
}
}

View File

@ -41,7 +41,6 @@ import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@ -124,6 +123,15 @@ public class TimeUnitTest extends JSR166TestCase {
assertEquals(t,
NANOSECONDS.convert(t, NANOSECONDS));
}
for (TimeUnit x : TimeUnit.values()) {
long[] zs = {
0, 1, -1,
Integer.MAX_VALUE, Integer.MIN_VALUE,
Long.MAX_VALUE, Long.MIN_VALUE,
};
for (long z : zs) assertEquals(z, x.convert(z, x));
}
}
/**
@ -308,6 +316,27 @@ public class TimeUnitTest extends JSR166TestCase {
NANOSECONDS.convert(Long.MAX_VALUE / 2, DAYS));
assertEquals(Long.MIN_VALUE,
NANOSECONDS.convert(-Long.MAX_VALUE / 4, DAYS));
for (TimeUnit x : TimeUnit.values())
for (TimeUnit y : TimeUnit.values()) {
long ratio = x.toNanos(1) / y.toNanos(1);
if (ratio >= 1) {
assertEquals(ratio, y.convert(1, x));
assertEquals(1, x.convert(ratio, y));
long max = Long.MAX_VALUE/ratio;
assertEquals(max * ratio, y.convert(max, x));
assertEquals(-max * ratio, y.convert(-max, x));
assertEquals(max, x.convert(max * ratio, y));
assertEquals(-max, x.convert(-max * ratio, y));
if (max < Long.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, y.convert(max + 1, x));
assertEquals(Long.MIN_VALUE, y.convert(-max - 1, x));
assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE + 1, x));
}
assertEquals(Long.MAX_VALUE, y.convert(Long.MAX_VALUE, x));
assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE, x));
}
}
}
/**
@ -319,6 +348,146 @@ public class TimeUnitTest extends JSR166TestCase {
MILLISECONDS.toNanos(Long.MAX_VALUE / 2));
assertEquals(Long.MIN_VALUE,
MILLISECONDS.toNanos(-Long.MAX_VALUE / 3));
for (TimeUnit x : TimeUnit.values()) {
long ratio = x.toNanos(1) / NANOSECONDS.toNanos(1);
if (ratio >= 1) {
long max = Long.MAX_VALUE/ratio;
for (long z : new long[] {0, 1, -1, max, -max})
assertEquals(z * ratio, x.toNanos(z));
if (max < Long.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toNanos(max + 1));
assertEquals(Long.MIN_VALUE, x.toNanos(-max - 1));
assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE + 1));
}
assertEquals(Long.MAX_VALUE, x.toNanos(Long.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE));
if (max < Integer.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toNanos(Integer.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toNanos(Integer.MIN_VALUE));
}
}
}
}
/**
* toMicros saturates positive too-large values to Long.MAX_VALUE
* and negative to LONG.MIN_VALUE
*/
public void testToMicrosSaturate() {
for (TimeUnit x : TimeUnit.values()) {
long ratio = x.toNanos(1) / MICROSECONDS.toNanos(1);
if (ratio >= 1) {
long max = Long.MAX_VALUE/ratio;
for (long z : new long[] {0, 1, -1, max, -max})
assertEquals(z * ratio, x.toMicros(z));
if (max < Long.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toMicros(max + 1));
assertEquals(Long.MIN_VALUE, x.toMicros(-max - 1));
assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE + 1));
}
assertEquals(Long.MAX_VALUE, x.toMicros(Long.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE));
if (max < Integer.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toMicros(Integer.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toMicros(Integer.MIN_VALUE));
}
}
}
}
/**
* toMillis saturates positive too-large values to Long.MAX_VALUE
* and negative to LONG.MIN_VALUE
*/
public void testToMillisSaturate() {
for (TimeUnit x : TimeUnit.values()) {
long ratio = x.toNanos(1) / MILLISECONDS.toNanos(1);
if (ratio >= 1) {
long max = Long.MAX_VALUE/ratio;
for (long z : new long[] {0, 1, -1, max, -max})
assertEquals(z * ratio, x.toMillis(z));
if (max < Long.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toMillis(max + 1));
assertEquals(Long.MIN_VALUE, x.toMillis(-max - 1));
assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE + 1));
}
assertEquals(Long.MAX_VALUE, x.toMillis(Long.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE));
if (max < Integer.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toMillis(Integer.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toMillis(Integer.MIN_VALUE));
}
}
}
}
/**
* toSeconds saturates positive too-large values to Long.MAX_VALUE
* and negative to LONG.MIN_VALUE
*/
public void testToSecondsSaturate() {
for (TimeUnit x : TimeUnit.values()) {
long ratio = x.toNanos(1) / SECONDS.toNanos(1);
if (ratio >= 1) {
long max = Long.MAX_VALUE/ratio;
for (long z : new long[] {0, 1, -1, max, -max})
assertEquals(z * ratio, x.toSeconds(z));
if (max < Long.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toSeconds(max + 1));
assertEquals(Long.MIN_VALUE, x.toSeconds(-max - 1));
assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE + 1));
}
assertEquals(Long.MAX_VALUE, x.toSeconds(Long.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE));
if (max < Integer.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toSeconds(Integer.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toSeconds(Integer.MIN_VALUE));
}
}
}
}
/**
* toMinutes saturates positive too-large values to Long.MAX_VALUE
* and negative to LONG.MIN_VALUE
*/
public void testToMinutesSaturate() {
for (TimeUnit x : TimeUnit.values()) {
long ratio = x.toNanos(1) / MINUTES.toNanos(1);
if (ratio > 1) {
long max = Long.MAX_VALUE/ratio;
for (long z : new long[] {0, 1, -1, max, -max})
assertEquals(z * ratio, x.toMinutes(z));
assertEquals(Long.MAX_VALUE, x.toMinutes(max + 1));
assertEquals(Long.MIN_VALUE, x.toMinutes(-max - 1));
assertEquals(Long.MAX_VALUE, x.toMinutes(Long.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE));
assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE + 1));
}
}
}
/**
* toHours saturates positive too-large values to Long.MAX_VALUE
* and negative to LONG.MIN_VALUE
*/
public void testToHoursSaturate() {
for (TimeUnit x : TimeUnit.values()) {
long ratio = x.toNanos(1) / HOURS.toNanos(1);
if (ratio >= 1) {
long max = Long.MAX_VALUE/ratio;
for (long z : new long[] {0, 1, -1, max, -max})
assertEquals(z * ratio, x.toHours(z));
if (max < Long.MAX_VALUE) {
assertEquals(Long.MAX_VALUE, x.toHours(max + 1));
assertEquals(Long.MIN_VALUE, x.toHours(-max - 1));
assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE + 1));
}
assertEquals(Long.MAX_VALUE, x.toHours(Long.MAX_VALUE));
assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE));
}
}
}
/**
@ -461,49 +630,4 @@ public class TimeUnitTest extends JSR166TestCase {
assertSame(x, serialClone(x));
}
/**
* tests for toChronoUnit.
*/
public void testToChronoUnit() throws Exception {
assertSame(ChronoUnit.NANOS, NANOSECONDS.toChronoUnit());
assertSame(ChronoUnit.MICROS, MICROSECONDS.toChronoUnit());
assertSame(ChronoUnit.MILLIS, MILLISECONDS.toChronoUnit());
assertSame(ChronoUnit.SECONDS, SECONDS.toChronoUnit());
assertSame(ChronoUnit.MINUTES, MINUTES.toChronoUnit());
assertSame(ChronoUnit.HOURS, HOURS.toChronoUnit());
assertSame(ChronoUnit.DAYS, DAYS.toChronoUnit());
// Every TimeUnit has a defined ChronoUnit equivalent
for (TimeUnit x : TimeUnit.values())
assertSame(x, TimeUnit.of(x.toChronoUnit()));
}
/**
* tests for TimeUnit.of(ChronoUnit).
*/
public void testTimeUnitOf() throws Exception {
assertSame(NANOSECONDS, TimeUnit.of(ChronoUnit.NANOS));
assertSame(MICROSECONDS, TimeUnit.of(ChronoUnit.MICROS));
assertSame(MILLISECONDS, TimeUnit.of(ChronoUnit.MILLIS));
assertSame(SECONDS, TimeUnit.of(ChronoUnit.SECONDS));
assertSame(MINUTES, TimeUnit.of(ChronoUnit.MINUTES));
assertSame(HOURS, TimeUnit.of(ChronoUnit.HOURS));
assertSame(DAYS, TimeUnit.of(ChronoUnit.DAYS));
assertThrows(NullPointerException.class,
() -> TimeUnit.of((ChronoUnit)null));
// ChronoUnits either round trip to their TimeUnit
// equivalents, or throw IllegalArgumentException.
for (ChronoUnit cu : ChronoUnit.values()) {
final TimeUnit tu;
try {
tu = TimeUnit.of(cu);
} catch (IllegalArgumentException acceptable) {
continue;
}
assertSame(cu, tu.toChronoUnit());
}
}
}

View File

@ -83,6 +83,10 @@ public class MultiReleaseJarAPI {
}
try (JarFile jf = new JarFile(multirelease)) {
Assert.assertFalse(jf.isMultiRelease());
}
try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
Assert.assertTrue(jf.isMultiRelease());
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"fooObject"})
@XmlRootElement(name = "Foo")
public class Foo {
protected List<Foo> fooObject;
public List<Foo> getFooObject() {
if (fooObject == null) {
fooObject = new ArrayList<Foo>();
}
return this.fooObject;
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8073872
* @summary test that stackoverflow is not observable when element
* references containing class
* @modules java.xml
* @modules java.xml.bind
* @compile Foo.java
* @run testng/othervm SchemagenStackOverflow
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import org.testng.Assert;
import org.testng.annotations.Test;
public class SchemagenStackOverflow {
@Test
public void schemagenStackOverflowTest() throws Exception {
// Create new instance of JAXB context
JAXBContext context = JAXBContext.newInstance(Foo.class);
context.generateSchema(new TestOutputResolver());
// Read schema content from file
String content = Files.lines(resultSchemaFile).collect(Collectors.joining(""));
System.out.println("Generated schema content:" + content);
// Check if schema was generated: check class and list object names
Assert.assertTrue(content.contains("name=\"Foo\""));
Assert.assertTrue(content.contains("name=\"fooObject\""));
}
// Schemagen output resolver
class TestOutputResolver extends SchemaOutputResolver {
@Override
public Result createOutput(String namespaceUri, String fileName)
throws IOException {
return new StreamResult(resultSchemaFile.toFile());
}
}
// Schemagen output file name and path
static final String SCHEMA_FILENAME = "generatedSchema.xsd";
Path resultSchemaFile = Paths.get(System.getProperty("user.dir", "."))
.resolve(SCHEMA_FILENAME);
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8134111
* @summary test that elements without namespace is ignored by unmarshaller
* when elementFormDefault is set to QUALIFIED.
* @compile testTypes/package-info.java testTypes/Root.java
* testTypes/WhenType.java testTypes/ObjectFactory.java
* @modules java.xml.bind
* @run testng/othervm UnmarshalTest
*/
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.testng.annotations.Test;
import static org.testng.Assert.assertNull;
import org.xml.sax.InputSource;
import testTypes.Root;
public class UnmarshalTest {
@Test
public void unmarshalUnexpectedNsTest() throws Exception {
JAXBContext context;
Unmarshaller unm;
// Create JAXB context from testTypes package
context = JAXBContext.newInstance("testTypes");
// Create unmarshaller from JAXB context
unm = context.createUnmarshaller();
// Unmarshall xml document with unqualified dtime element
Root r = (Root) unm.unmarshal(new InputSource(new StringReader(DOC)));
// Print dtime value and check if it is null
System.out.println("dtime is:"+r.getWhen().getDtime());
assertNull(r.getWhen().getDtime());
}
//Xml document to unmarshall with unqualified dtime element
private final String DOC =
"<tns:root xmlns:tns=\"http://www.example.org/testNamespace/\">" +
"<tns:when>" +
"<dtime>2015-06-24T13:16:14.933-04:00</dtime>" +
"</tns:when>" +
"</tns:root>";
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package testTypes;
import javax.xml.bind.annotation.XmlRegistry;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the testTypes package.
*
*/
@XmlRegistry
public class ObjectFactory {
/**
* Create a new ObjectFactory that can be used to create
* new instances of schema derived classes for package: testTypes
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link Root }
*
*/
public Root createRoot() {
return new Root();
}
/**
* Create an instance of {@link WhenType }
*
*/
public WhenType createWhenType() {
return new WhenType();
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package testTypes;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"when"})
@XmlRootElement(name = "root",
namespace = "http://www.example.org/testNamespace/")
public class Root {
@XmlElement(required = true,
namespace = "http://www.example.org/testNamespace/")
protected WhenType when;
/**
* Gets the value of the when property.
*
* @return
* possible object is
* {@link WhenType }
*
*/
public WhenType getWhen() {
return when;
}
/**
* Sets the value of the when property.
*
* @param value
* allowed object is
* {@link WhenType }
*
*/
public void setWhen(WhenType value) {
this.when = value;
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package testTypes;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* <p>Java class for WhenType complex type.
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "WhenType",
propOrder = {"dtime"})
public class WhenType {
@XmlElement(required = true)
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar dtime;
/**
* Gets the value of the dtime property.
*
* @return
* possible object is
* {@link XMLGregorianCalendar }
*
*/
public XMLGregorianCalendar getDtime() {
return dtime;
}
/**
* Sets the value of the dtime property.
*
* @param value
* allowed object is
* {@link XMLGregorianCalendar }
*
*/
public void setDtime(XMLGregorianCalendar value) {
this.dtime = value;
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
@javax.xml.bind.annotation.XmlSchema(
namespace = "http://www.example.org/testNamespace/",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package testTypes;

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* Basic jrt file system functionality testing
*
*/
public class Main {
public static void main(String[] args) throws Exception {
String javaHome = args[0];
FileSystem fs = null;
boolean isInstalled = false;
if (args.length == 2) {
fs = createFsByInstalledProvider();
isInstalled = true;
} else {
fs = createFsWithURLClassloader(javaHome);
}
Path mods = fs.getPath("/modules");
try (Stream<Path> stream = Files.walk(mods)) {
stream.forEach(path -> {
path.getFileName();
});
} finally {
try {
fs.close();
} catch (UnsupportedOperationException e) {
if (!isInstalled) {
throw new RuntimeException(
"UnsupportedOperationException is thrown unexpectedly");
}
}
}
}
private static FileSystem createFsWithURLClassloader(String javaHome) throws IOException{
URL url = Paths.get(javaHome, "jrt-fs.jar").toUri().toURL();
URLClassLoader loader = new URLClassLoader(new URL[] { url });
return FileSystems.newFileSystem(URI.create("jrt:/"), null, loader);
}
private static FileSystem createFsByInstalledProvider() throws IOException {
return FileSystems.getFileSystem(URI.create("jrt:/"));
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8141609
* @summary Verify JDK 8 can use jrt-fs.jar to work with jrt file system.
* @run main RemoteRuntimeImageTest
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.FileSystems;
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.Properties;
public class RemoteRuntimeImageTest {
//the jrt-fs.jar shipped together with jdk
private static final String JRTFS_JAR = "jrt-fs.jar";
private static final String SRC_DIR = System.getProperty("test.src");
private static final String CLASSES_DIR = "classes";
private static final String TEST_JAVAHOME = System.getProperty("test.jdk");
public static void main(String[] args) throws Exception {
// By default, set to ${JT_JAVA}
String jdk8Home = System.getenv("JDK8_HOME");
if (jdk8Home == null || jdk8Home.isEmpty()) {
System.err.println("Failed to locate JDK8 with system "
+ "environment variable 'JDK8_HOME'. Skip testing!");
return;
}
Path jdk8Path = getJdk8Path(jdk8Home);
if (!isJdk8(jdk8Path)) {
System.err.println("This test is only for JDK 8. Skip testing");
return;
}
String java = jdk8Path.resolve("bin/java").toAbsolutePath().toString();
String javac = jdk8Path.resolve("bin/javac").toAbsolutePath().toString();
Files.createDirectories(Paths.get(".", CLASSES_DIR));
String jrtJar = Paths.get(TEST_JAVAHOME, JRTFS_JAR).toAbsolutePath().toString();
// Compose command-lines for compiling and executing tests
List<List<String>> cmds = Arrays.asList(
// Commands to compile test classes
Arrays.asList(javac, "-d", CLASSES_DIR, "-cp", jrtJar,
SRC_DIR + File.separatorChar + "Main.java"),
// Run test
Arrays.asList(java, "-cp", CLASSES_DIR, "Main", TEST_JAVAHOME),
// Run test with jrtfs.jar in class path,
// which means to install jrt FileSystem provider
Arrays.asList(java, "-cp", CLASSES_DIR + File.pathSeparatorChar + jrtJar,
"Main", TEST_JAVAHOME, "installed")
);
cmds.forEach(cmd -> execCmd(cmd));
}
private static void execCmd(List<String> command){
System.out.println();
System.out.println("Executing command: " + command);
Process p = null;
try {
p = new ProcessBuilder(command).inheritIO().start();
p.waitFor();
int rc = p.exitValue();
if (rc != 0) {
throw new RuntimeException("Unexpected exit code:" + rc);
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (p != null && p.isAlive()){
p.destroy();
}
}
}
private static Path getJdk8Path(String jdk8Home) {
Path jdk8Path = Paths.get(jdk8Home);
// It is possible to point to the path of java executable by ${JT_JAVA}
return Files.isDirectory(jdk8Path)? jdk8Path : jdk8Path.getParent().getParent();
}
private static boolean isJdk8(Path jdk8Home) throws FileNotFoundException, IOException {
File file = jdk8Home.resolve("release").toFile();
Properties props = new Properties();
try (FileInputStream in = new FileInputStream(file)) {
props.load(in);
}
String version = props.getProperty("JAVA_VERSION", "");
System.out.println("JAVA_VERSION is " + version);
return version.startsWith("\"1.8");
}
}

View File

@ -0,0 +1,45 @@
This suite contains automated client sanity tests which can be run using JTReg.
Contact alexander.kouznetsov@oracle.com in case of issues.
-------------------------------------------------------------------------------
How to run:
1) Download/Install the JDK to be tested in the system.
(For example C:/java/jdk1.9.0 in windows or
/export/jdk/jdk1.9.0 in linux/mac/solaris)
2) Download/Install JTReg harness, minimum required version is 4.1 b13.
3) Open terminal(cmd in windows, *not* cygwin) and go to the this directory.
4) To run
- see the notes below on how to prepare for the test run
- set JT_HOME to <path/to/jtreg>, for example
set JT_HOME=C:\Java\client\jtreg (Windows)
- run the command
'sh <path/to/jtreg/bin/jtreg> -ea -k:\!screenshots -jdk:<Path/to/JDK> SwingSet'
For example: 'sh C:/jtreg/bin/jtreg -ea -k:\!screenshots -jdk:C:/java/jdk1.9.0 SwingSet' (Windows)
'sh /export/jtreg/bin/jtreg -ea -k:\!screenshots -jdk:/export/jdk/jdk1.9.0 SwingSet' (Linux/Solaris)
'sh /export/jtreg/bin/jtreg -ea -k:\!screenshots -jdk:/export/jdk/jdk1.9.0/Contents/Home SwingSet' (Mac)
Try to minimize all the other windows for no interference and test stability.
Do not touch keyboard or mouse, open any window, nor lock the screen while the tests are running.
The tests will be executed, and the results will be displayed in the terminal.
A report will be generated under
a) JTReg: "JTReport/index.html".
The failure logs could be found under:
a) JTReg: "JTWork/<testname>/<testname>.jtr"
The following additional options might be useful:
-retain:all to keep work files for passed tests
-k:\!screenshots removal of this option will run tests that require full environment with Robot and screenshots
-g to run JavaTest GUI
-------------------------------------------------------------------------------
The tests in the suite are based on SwingSet3 demo application. They use Jemmy to
operate on controls of the demo and verify that it is behaving as expected. Both
Jemmy and SwingSet3 sources are available as copies in lib folder.
Original Jemmy repository is https://jemmy.java.net
Original SwingSet3 repository is https://java.net/projects/swingset3

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.image.BufferedImage;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.image.StrictImageComparator;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import static org.jemmy2ext.JemmyExt.*;
import org.testng.annotations.Test;
import static com.sun.swingset3.demos.button.ButtonDemo.*;
/*
* @test
* @key headful screenshots
* @summary Verifies buttons on SwingSet3 ButtonDemo page by clicking each
* button, taking its screenshots and checking that pressed button
* image is different from initial button image.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.button.ButtonDemo
* @run testng ButtonDemoScreenshotTest
*/
public class ButtonDemoScreenshotTest {
private static final int BUTTON_COUNT = 6; // TODO: Decide about "open browser" buttons (value was 8 originally)
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
Robot rob = new Robot();
new ClassReference(com.sun.swingset3.demos.button.ButtonDemo.class.getCanonicalName()).startApplication();
JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
waitImageIsStill(rob, mainFrame);
// Check all the buttons
for (int i = 0; i < BUTTON_COUNT; i++) {
checkButton(mainFrame, i, rob);
}
});
}
public void checkButton(JFrameOperator jfo, int i, Robot rob) {
JButtonOperator button = new JButtonOperator(jfo, i);
Point loc = button.getLocationOnScreen();
rob.mouseMove(loc.x, loc.y);
BufferedImage initialButtonImage = capture(rob, button);
assertNotBlack(initialButtonImage);
save(initialButtonImage, "button" + i + "_0initial.png");
rob.mousePress(InputEvent.BUTTON1_MASK);
try {
waitPressed(button);
BufferedImage pressedButtonImage = capture(rob, button);
assertNotBlack(pressedButtonImage);
save(pressedButtonImage, "button" + i + "_1pressed.png");
StrictImageComparator sComparator = new StrictImageComparator();
assertNotEquals("Button " + i + " Test", sComparator, initialButtonImage, pressedButtonImage);
} finally {
rob.mouseRelease(InputEvent.BUTTON1_MASK);
}
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.JHyperlink;
import com.sun.swingset3.demos.button.ButtonDemo;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.event.ChangeEvent;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.jemmy2ext.JemmyExt.ByToolTipChooser;
import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import static com.sun.swingset3.demos.button.ButtonDemo.*;
import org.jemmy2ext.JemmyExt;
import org.jemmy2ext.JemmyExt.MultiThreadedTryCatch;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies buttons on SwingSet3 ButtonDemo page by clicking each button
* and checking model change events. It also verifies tooltips and text
* on buttons before and after click.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.button.ButtonDemo
* @run testng ButtonDemoTest
*/
public class ButtonDemoTest {
private static final String[] BUTTON_TEXT_AFTER = {
DO_IT_AGAIN,};
private static final String[] BUTTON_TEXT_BEFORE = {
DO_IT,
"",
FIND,
GO,
CONNECT,
"",
GET_MORE_INFO,
null
};
private static final String[] BUTTON_TOOLTIP = {
SIMPLE_BUTTON,
IMAGE_BUTTON,
BUTTON_WITH_TEXT_AND_IMAGE,
BUTTON_WITH_BACKGROUND_COLOR,
BUTTON_WITH_NO_BORDER,
BUTTON_WITH_ROLLOVER_IMAGE,
JAVA_SE_URL,
JAVA_BLOGS_URL
};
private static final String[] GOLDEN = {
"isArmed = false, isEnabled = true, isPressed = false, isSelected = false",
"isArmed = true, isEnabled = true, isPressed = false, isSelected = false",
"isArmed = true, isEnabled = true, isPressed = true, isSelected = false",
"isArmed = true, isEnabled = true, isPressed = false, isSelected = false",
"isArmed = false, isEnabled = true, isPressed = false, isSelected = false"
};
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
mainFrame.setComparator(EXACT_STRING_COMPARATOR);
// Check all the buttons
for (int i = 0; i < BUTTON_TOOLTIP.length; i++) {
String tooltip = BUTTON_TOOLTIP[i];
JButtonOperator button = new JButtonOperator(mainFrame, new ByToolTipChooser(tooltip));
assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
// Two buttons are hyperlinks, we don't want to click them
if (!button.getSource().getClass().equals(JHyperlink.class)) {
checkButton(button);
}
if (BUTTON_TEXT_AFTER.length > i) {
assertEquals(BUTTON_TEXT_AFTER[i], button.getText());
} else {
assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
}
}
});
}
private void checkButton(JButtonOperator button) throws Exception {
MultiThreadedTryCatch tryCatch = new JemmyExt.MultiThreadedTryCatch();
try {
BlockingQueue<String> modelStateChanges = new ArrayBlockingQueue<>(GOLDEN.length);
button.getQueueTool().invokeAndWait(() -> {
try {
JButton jButton = (JButton) button.getSource();
ButtonModel model = jButton.getModel();
String line = toString(model);
System.out.println("Inital: " + line);
modelStateChanges.add(line);
model.addChangeListener((ChangeEvent e) -> {
try {
String line2 = toString(model);
System.out.println("ChangeEvent: " + line2);
// We are only interested in the first GOLDEN.length events
if (modelStateChanges.remainingCapacity() > 0) {
modelStateChanges.add(line2);
}
} catch (RuntimeException | Error t) {
tryCatch.register(t);
}
});
} catch (Error error) {
// All exceptions are already handled by Jemmy but Errors are not
tryCatch.register(error);
throw error;
}
});
assertEquals("Initial state check", GOLDEN[0], modelStateChanges.take());
button.clickMouse();
for (int state = 1; state < GOLDEN.length; state++) {
assertEquals(GOLDEN[state], modelStateChanges.take());
}
} catch (RuntimeException | Error | InterruptedException t) {
tryCatch.registerRoot(t);
} finally {
tryCatch.throwRegistered();
}
}
private static String toString(ButtonModel model) {
return "isArmed = " + model.isArmed()
+ ", isEnabled = " + model.isEnabled()
+ ", isPressed = " + model.isPressed()
+ ", isSelected = " + model.isSelected();
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.combobox.ComboBoxDemo;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JComboBoxOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import static com.sun.swingset3.demos.combobox.ComboBoxDemo.*;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies ComboBoxes on SwingSet2 ComboBoxDemo page by selecting
* each value of each ComboBox.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.combobox.ComboBoxDemo
* @run testng ComboBoxDemoTest
*/
public class ComboBoxDemoTest {
private static enum ComboBoxInfo {
PRESETS("Presets:"),
HAIR("Hair:"),
EYES_N_NOSE("Eyes & Nose:"),
MOUTH("Mouth:");
private final String comboBoxName;
private ComboBoxInfo(String comboBoxName) {
this.comboBoxName = comboBoxName;
}
}
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(ComboBoxDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
for (ComboBoxInfo comboBoxInfo : ComboBoxInfo.values()) {
comboBoxChecker(frame, comboBoxInfo);
}
});
}
private void comboBoxChecker(JFrameOperator jfo, ComboBoxInfo comboBoxInfo) {
JComboBoxOperator jcbo = new JComboBoxOperator(jfo, comboBoxInfo.ordinal());
for (int i = 0; i < jcbo.getItemCount(); i++) {
jcbo.selectItem(i);
assertEquals(comboBoxInfo.comboBoxName + " ComboBox SelectedIndex is correct", i, jcbo.getSelectedIndex());
}
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.list.ListDemo;
import static com.sun.swingset3.demos.list.ListDemo.DEMO_TITLE;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JCheckBoxOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JListOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 ListDemo page by checking and unchecking all
* the checkboxes on the page and verifying the number of items in the
* list.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.list.ListDemo
* @run testng ListDemoTest
*/
public class ListDemoTest {
private static final int CHECKBOX_COUNT = 50;
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(ListDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
JListOperator listOp = new JListOperator(frame);
// Check *NO* Prefix and Suffixes Marked
for (int i = 0; i < CHECKBOX_COUNT; i++) {
JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
checkBox.changeSelection(false);
}
System.out.println("######## Number of Items = " + listOp.getModel().getSize());
assertEquals("Select None number of items is correct", 0, listOp.getModel().getSize());
// Check *ALL* Prefix and Suffixes Marked
for (int i = 0; i < CHECKBOX_COUNT; i++) {
JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
checkBox.changeSelection(true);
}
System.out.println("######## Number of Items = " + listOp.getModel().getSize());
assertEquals("Select All number of items is correct", CHECKBOX_COUNT / 2 * CHECKBOX_COUNT / 2, listOp.getModel().getSize());
// Check *ALL* Prefix and *NO* Suffixes Marked
for (int i = 0; i < CHECKBOX_COUNT; i++) {
JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
if (i < CHECKBOX_COUNT / 2) {
checkBox.changeSelection(true);
} else {
checkBox.changeSelection(false);
}
}
System.out.println("######## Number of Items = " + listOp.getModel().getSize());
assertEquals("Select All Prefixes and NO Suffixes number of items is correct", 0, listOp.getModel().getSize());
// Check *NO* Prefix and *ALL* Suffixes Marked
for (int i = 0; i < CHECKBOX_COUNT; i++) {
JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
if (i < CHECKBOX_COUNT / 2) {
checkBox.changeSelection(false);
} else {
checkBox.changeSelection(true);
}
}
System.out.println("######## Number of Items = " + listOp.getModel().getSize());
assertEquals("Select NO Prefixes and All Suffixes number of items is correct", 0, listOp.getModel().getSize());
});
}
private JCheckBoxOperator getJCheckBoxOperator(JFrameOperator frame, int index) {
// We map first half of indexes to the Prefixes panel and the second half
// to the Suffixes panel
String labelText;
int subindex;
if (index < CHECKBOX_COUNT / 2) {
labelText = "Prefixes";
subindex = index;
} else {
labelText = "Suffixes";
subindex = index - CHECKBOX_COUNT / 2;
}
return new JCheckBoxOperator(getLabeledContainerOperator(frame, labelText), subindex);
}
}

View File

@ -0,0 +1,339 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.optionpane.OptionPaneDemo;
import static com.sun.swingset3.demos.optionpane.OptionPaneDemo.*;
import javax.swing.UIManager;
import static org.jemmy2ext.JemmyExt.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JComboBoxOperator;
import org.netbeans.jemmy.operators.JDialogOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 OptionPaneDemo page by opening all the dialogs
* and choosing different options in them.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.optionpane.OptionPaneDemo
* @run testng OptionPaneDemoTest
*/
public class OptionPaneDemoTest {
public static final String SOME_TEXT_TO_TYPE = "I am some text";
public static final String MESSAGE = UIManager.getString("OptionPane.messageDialogTitle");
public static final String OK = "OK";
public static final String CANCEL = "Cancel";
public static final String INPUT = UIManager.getString("OptionPane.inputDialogTitle");
public static final String TEXT_TO_TYPE = "Hooray! I'm a textField";
public static final String NO = "No";
public static final String YES = "Yes";
public static final String SELECT_AN__OPTION = UIManager.getString("OptionPane.titleText");
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(OptionPaneDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
showInputDialog(frame);
showWarningDialog(frame);
showMessageDialog(frame);
showComponentDialog(frame);
showConfirmationDialog(frame);
});
}
public void showInputDialog(JFrameOperator jfo) throws Exception {
// Cancel with text case
{
new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(INPUT);
JTextFieldOperator jto = new JTextFieldOperator(jdo);
jto.setText(SOME_TEXT_TO_TYPE);
assertTrue("Show Input Dialog cancel w/ Text", jdo.isShowing());
new JButtonOperator(jdo, CANCEL).push();
assertFalse("Show Input Dialog cancel w/ Text", jdo.isShowing());
}
// Cancel with *NO* text case
{
new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(INPUT);
assertTrue("Show Input Dialog cancel w/o Text", jdo.isShowing());
new JButtonOperator(jdo, CANCEL).push();
assertFalse("Show Input Dialog cancel w/o Text", jdo.isShowing());
}
// Text field has *NO* input
{
new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(INPUT);
assertTrue("Show Input Dialog w/o Input", jdo.isShowing());
new JButtonOperator(jdo, OK).push();
assertFalse("Show Input Dialog w/o Input", jdo.isShowing());
}
// Text field has input
{
final String enteredText = "Rambo";
new JButtonOperator(jfo, INPUT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(INPUT);
JTextFieldOperator jto = new JTextFieldOperator(jdo);
jto.setText(enteredText);
new JButtonOperator(jdo, OK).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Show Input Dialog w/ Input", jdo1.isShowing());
final String labelText = enteredText + INPUT_RESPONSE;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Text from the field made it into the dialog", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Show Input Dialog w/ Input", jdo1.isShowing());
}
}
public void showWarningDialog(JFrameOperator jfo) throws Exception {
new JButtonOperator(jfo, WARNING_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(WARNING_TITLE);
assertTrue("Show Warning Dialog", jdo.isShowing());
new JButtonOperator(jdo, OK).push();
assertFalse("Show Warning Dialog", jdo.isShowing());
}
public void showMessageDialog(JFrameOperator jfo) throws Exception {
new JButtonOperator(jfo, MESSAGE_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(MESSAGE);
assertTrue("Show Message Dialog", jdo.isShowing());
new JButtonOperator(jdo, OK).push();
assertFalse("Show Message Dialog", jdo.isShowing());
}
public void showComponentDialog(JFrameOperator jfo) throws Exception {
// Case: Cancel
{
new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
assertTrue("Show Component Dialog Cancel Option", jdo.isShowing());
new JButtonOperator(jdo, COMPONENT_OP5).push();
assertFalse("Show Component Dialog Cancel Option", jdo.isShowing());
}
// Case: Yes option selected
{
new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
new JButtonOperator(jdo, COMPONENT_OP1).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Component Dialog Example Yes Option", jdo1.isShowing());
final String labelText = COMPONENT_R1;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Component Dialog Example Yes Option", jdo1.isShowing());
}
// Case: No option selected
{
new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
new JButtonOperator(jdo, COMPONENT_OP2).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Component Dialog Example No Option", jdo1.isShowing());
final String labelText = COMPONENT_R2;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Component Dialog Example No Option", jdo1.isShowing());
}
// Case: Maybe option selected
{
new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
new JButtonOperator(jdo, COMPONENT_OP3).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Component Dialog Maybe Yes Option", jdo1.isShowing());
final String labelText = COMPONENT_R3;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Component Dialog Maybe Yes Option", jdo1.isShowing());
}
// Case: Probably option selected
{
new JButtonOperator(jfo, COMPONENT_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
new JButtonOperator(jdo, COMPONENT_OP4).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Component Dialog Example Probably Option", jdo1.isShowing());
final String labelText = COMPONENT_R4;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Component Dialog Example Probably Option", jdo1.isShowing());
}
// Case TextField and ComboBox functional
{
new JButtonOperator(jfo, COMPONENT_BUTTON).push();
JDialogOperator jdo = new JDialogOperator(COMPONENT_TITLE);
JTextFieldOperator jto = new JTextFieldOperator(jdo);
jto.clearText();
jto.typeText(TEXT_TO_TYPE);
JComboBoxOperator jcbo = new JComboBoxOperator(jdo);
jcbo.selectItem(2);
assertEquals("Show Component Dialog TextField", TEXT_TO_TYPE, jto.getText());
assertEquals("Show Component Dialog ComboBox", 2, jcbo.getSelectedIndex());
new JButtonOperator(jdo, "cancel").push();
}
}
public void showConfirmationDialog(JFrameOperator jfo) throws Exception {
// Case: Yes option selected
{
new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
new JButtonOperator(jdo, YES).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Show Confirmation Dialog Yes Option", jdo1.isShowing());
final String labelText = CONFIRM_YES;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Show Confirmation Dialog Yes Option", jdo1.isShowing());
}
// Case: No option selected
{
new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
new JButtonOperator(jdo, NO).pushNoBlock();
JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
assertTrue("Show Confirmation Dialog No Option", jdo1.isShowing());
final String labelText = CONFIRM_NO;
JLabelOperator jLabelOperator = new JLabelOperator(jdo1, labelText);
assertEquals("Dialog contains appropriate text", labelText, jLabelOperator.getText());
new JButtonOperator(jdo1, OK).push();
assertFalse("Show Confirmation Dialog No Option", jdo1.isShowing());
}
// Case: Cancel option selected
{
new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
assertTrue("Show Confirmation Dialog Cancel Option", jdo.isShowing());
new JButtonOperator(jdo, CANCEL).push();
assertFalse("Show Confirmation Dialog Cancel Option", jdo.isShowing());
}
}
}

View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.progressbar.ProgressBarDemo;
import static com.sun.swingset3.demos.progressbar.ProgressBarDemo.*;
import java.awt.Component;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.ComponentChooser;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JProgressBarOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 ProgressBarDemo page by pressing start and stop
* buttons and checking the progress bar and the buttons state.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.progressbar.ProgressBarDemo
* @run testng ProgressBarDemoTest
*/
public class ProgressBarDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(ProgressBarDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
JButtonOperator startButton = new JButtonOperator(frame, START_BUTTON);
JButtonOperator stopButton = new JButtonOperator(frame, STOP_BUTTON);
JProgressBarOperator jpbo = new JProgressBarOperator(frame);
// Check that progress completes and corect enable/disable of start/stop buttons
checkCompleteProgress(frame, startButton, stopButton, jpbo);
// Check progess bar progression and start/stop button disabled/enabled states
checkStartStop(frame, startButton, stopButton, jpbo);
});
}
// Check that progress completes and corect enable/disable of start/stop buttons
public void checkStartStop(JFrameOperator frame, JButtonOperator startButton, JButtonOperator stopButton, JProgressBarOperator progressBar) throws Exception {
int initialProgress = progressBar.getValue();
System.out.println("initialProgress = " + initialProgress);
int maximum = progressBar.getMaximum();
startButton.pushNoBlock();
progressBar.waitState(new ComponentChooser() {
@Override
public boolean checkComponent(Component comp) {
int value = progressBar.getValue();
System.out.println("checkComponent1 value = " + value);
return value < maximum;
}
@Override
public String getDescription() {
return "Progress < maximum (" + maximum + ")";
}
});
stopButton.waitComponentEnabled();
progressBar.waitState(new ComponentChooser() {
@Override
public boolean checkComponent(Component comp) {
int value = progressBar.getValue();
System.out.println("checkComponent2 value = " + value);
return value > 0;
}
@Override
public String getDescription() {
return "Progress > 0";
}
});
int progress = progressBar.getValue();
System.out.println("progress = " + progress);
//Check that progress par has progressed and Start Button Disabled
assertTrue("Progress Bar Progressing (progress > 0, actual value: " + progress + ")", progress > 0);
assertFalse("Start Button Disabled", startButton.isEnabled());
assertTrue("Stop Button Enabled", stopButton.isEnabled());
//Wait a liitle bit longer then Press stop get progress
progressBar.waitState(new ComponentChooser() {
@Override
public boolean checkComponent(Component comp) {
return progressBar.getValue() > progress;
}
@Override
public String getDescription() {
return "Progress > " + progress;
}
});
stopButton.pushNoBlock();
startButton.waitComponentEnabled();
int interimProgress = progressBar.getValue();
// Check that progress par has Stopped and Start Button Disabled
assertTrue("Progress Bar Stopped "
+ "(interimProgress, actual value: " + interimProgress + " "
+ "> progress, actual value: " + progress + ")",
interimProgress > progress);
assertTrue("Start Button Enabled", startButton.isEnabled());
assertFalse("Stop Button Disabled", stopButton.isEnabled());
}
// Check progess bar progression and start/stop button disabled/enabled states
public void checkCompleteProgress(JFrameOperator frame, JButtonOperator startButton, JButtonOperator stopButton, JProgressBarOperator progressBar) throws Exception {
startButton.pushNoBlock();
progressBar.waitValue(progressBar.getMaximum());
startButton.waitComponentEnabled();
assertEquals("Complete Progress", progressBar.getMaximum(), progressBar.getValue());
assertTrue("Start Button Enabled", startButton.isEnabled());
assertFalse("Stop Button Disabled", stopButton.isEnabled());
}
}

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.scrollpane.ScrollPaneDemo;
import static com.sun.swingset3.demos.scrollpane.ScrollPaneDemo.DEMO_TITLE;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JScrollPaneOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 ScrollPaneDemo by scrolling to bottom, to top,
* to left and to right and checking scroll bar values.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.scrollpane.ScrollPaneDemo
* @run testng ScrollPaneDemoTest
*/
public class ScrollPaneDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(ScrollPaneDemo.class.getName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
JScrollPaneOperator jspo = new JScrollPaneOperator(frame);
// Set initial scrollbar positions
int initialVerticalValue = jspo.getVerticalScrollBar().getValue();
int initialHorizontalValue = jspo.getHorizontalScrollBar().getValue();
System.out.println("Initial Vertical Value = " + jspo.getVerticalScrollBar().getValue());
System.out.println("Initial HoriZontal Value = " + jspo.getHorizontalScrollBar().getValue());
// Check scroll to Bottom
{
jspo.scrollToBottom();
int currentValue = jspo.getVerticalScrollBar().getValue();
System.out.println("Final Value = " + currentValue);
assertTrue("Scroll to Bottom of Pane "
+ "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+ "< currentValue, actual value = " + currentValue + ")",
initialVerticalValue < currentValue);
}
// Check scroll to Top
{
jspo.scrollToTop();
int currentValue = jspo.getVerticalScrollBar().getValue();
System.out.println("Top Scroll Final Value = " + currentValue);
assertTrue("Scroll to Top of Pane "
+ "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+ "> currentValue, actual value = " + currentValue + ")",
initialVerticalValue > currentValue);
}
// Check scroll to Left
{
jspo.scrollToLeft();
int currentValue = jspo.getHorizontalScrollBar().getValue();
System.out.println("Scroll to Left Final Value = " + currentValue);
assertTrue("Scroll to Left of Pane "
+ "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+ "> currentValue, actual value = " + currentValue + ")",
initialHorizontalValue > currentValue);
}
// Check scroll to Right
{
jspo.scrollToRight();
int currentValue = jspo.getHorizontalScrollBar().getValue();
System.out.println("Scroll to Right Final Value = " + currentValue);
assertTrue("Scroll to Right of Pane "
+ "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+ "< currentValue, actual value = " + currentValue + ")",
initialHorizontalValue < currentValue);
}
});
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.spinner.SpinnerDemo;
import static com.sun.swingset3.demos.spinner.SpinnerDemo.DEMO_TITLE;
import java.text.DecimalFormat;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JSpinnerOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 SpinnerDemo by adjusting each spinner value via
* the spinner button and checking text field value.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.spinner.SpinnerDemo
* @run testng SpinnerDemoTest
*/
public class SpinnerDemoTest {
private static final int SPINNERS_COUNT = 9;
private static final DecimalFormat decimalFormat = new DecimalFormat();
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(SpinnerDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
// Check changing different spinners
for (int i = 0; i < SPINNERS_COUNT; i++) {
changeValues(frame, i);
}
});
}
private void changeValues(JFrameOperator jfo, int spinnerIndex) throws Exception {
JSpinnerOperator spinner = new JSpinnerOperator(jfo, spinnerIndex);
JTextFieldOperator jtfo = new JTextFieldOperator(spinner);
float originalFieldValue = decimalFormat.parse(jtfo.getText()).floatValue();
float finalFieldValue;
// increment by one the value via spinner
spinner.getIncreaseOperator().push();
finalFieldValue = decimalFormat.parse(jtfo.getText()).floatValue();
// check that the value was increased
assertTrue("Increment Spinner " + spinner
+ " (originalFieldValue, actual value: " + originalFieldValue + " "
+ "< finalFieldValue, actual value = " + finalFieldValue + ")",
originalFieldValue < finalFieldValue);
// decrease value via spinner
spinner.getDecreaseOperator().push();
finalFieldValue = decimalFormat.parse(jtfo.getText()).floatValue();
// check that the value was decrimented
assertTrue("Decrement Spinner " + spinner
+ " (originalFieldValue, actual value: " + originalFieldValue + " "
+ ">= finalFieldValue, actual value = " + finalFieldValue + ")",
originalFieldValue >= finalFieldValue);
}
}

View File

@ -0,0 +1,174 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.splitpane.SplitPaneDemo;
import static com.sun.swingset3.demos.splitpane.SplitPaneDemo.*;
import java.awt.event.KeyEvent;
import javax.swing.JSplitPane;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JCheckBoxOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JRadioButtonOperator;
import org.netbeans.jemmy.operators.JSplitPaneOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
import static org.jemmy2ext.JemmyExt.*;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 SplitPaneDemo by performing OneClick expansion,
* changing size of the divier, moving the divider to different positions
* and changing the divider orientation.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.splitpane.SplitPaneDemo
* @run testng SplitPaneDemoTest
*/
public class SplitPaneDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(SplitPaneDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
JSplitPaneOperator splitPane = new JSplitPaneOperator(frame);
// Toggle OneTouch Expandable
checkOneTouch(frame, splitPane, true);
checkOneTouch(frame, splitPane, false);
// Check changing divider size to minimum and maximum values
changeDividerSize(frame, splitPane, 50);
changeDividerSize(frame, splitPane, 6);
// Check moving the divider
checkDividerMoves(frame, splitPane, false);
checkDividerMoves(frame, splitPane, true);
// Check different minumum Day/Night sizes
changeMinimumSizes(frame, splitPane, 100);
changeMinimumSizes(frame, splitPane, 0);
});
}
// Check for different day and night minimum size
public void changeMinimumSizes(JFrameOperator frame, JSplitPaneOperator splitPane, int amount) throws Exception {
for (String label : new String[]{FIRST_COMPONENT_MIN_SIZE, SECOND_COMPONENT_MIN_SIZE}) {
JTextFieldOperator size = new JTextFieldOperator(getLabeledContainerOperator(frame, label));
size.enterText(Integer.toString(amount));
size.pressKey(KeyEvent.VK_ENTER);
}
checkDividerMoves(frame, splitPane, false);
checkDividerMoves(frame, splitPane, true);
}
// Check moving of divider
public void checkDividerMoves(JFrameOperator frame, JSplitPaneOperator splitPane, boolean isVertical) throws Exception {
if (isVertical) {
new JRadioButtonOperator(frame, VERTICAL_SPLIT).doClick();
} else {
new JRadioButtonOperator(frame, HORIZONTAL_SPLIT).doClick();
}
splitPane.moveDivider(0.0);
assertEquals("Move Minimum, dividerLocation is at minimumDividerLocation",
splitPane.getMinimumDividerLocation(), splitPane.getDividerLocation());
// use getMaximumDividerLocation() to move divider to here because using proportion 1.0 does not work
splitPane.moveDivider(1.0);
assertEquals("Move Maximum, dividerLocation is at maximumDividerLocation",
splitPane.getMaximumDividerLocation(), splitPane.getDividerLocation());
splitPane.moveDivider(0.5);
assertEquals("Move Middle, dividerLocation is at the artithmetic average of minimum and maximum DividerLocations",
(splitPane.getMaximumDividerLocation() + splitPane.getMinimumDividerLocation()) / 2, splitPane.getDividerLocation());
}
// Check changing the size of the divider
public void changeDividerSize(JFrameOperator frame, JSplitPaneOperator splitPane, int amount) throws Exception {
JTextFieldOperator size = new JTextFieldOperator(getLabeledContainerOperator(frame, DIVIDER_SIZE));
size.clearText();
size.typeText(Integer.toString(amount));
size.pressKey(KeyEvent.VK_ENTER);
assertEquals("Change Divider Size", amount, splitPane.getDividerSize());
}
public void checkOneTouch(JFrameOperator frame, JSplitPaneOperator splitPane, boolean oneTouch) throws Exception {
JCheckBoxOperator checkBox = new JCheckBoxOperator(frame, ONE_TOUCH_EXPANDABLE);
JButtonOperator buttonLeft = new JButtonOperator(splitPane.getDivider(), 0);
JButtonOperator buttonRight = new JButtonOperator(splitPane.getDivider(), 1);
int initDividerLocation = splitPane.getDividerLocation();
if (oneTouch) {
if (!checkBox.isSelected()) {
// uncheck
checkBox.doClick();
}
int left = getUIValue(splitPane, (JSplitPane sp) -> sp.getInsets().left);
System.out.println("left = " + left);
int right = getUIValue(splitPane, (JSplitPane sp) -> sp.getInsets().right);
System.out.println("right = " + right);
// expand full left
buttonLeft.push();
assertEquals("Expandable Left", left, splitPane.getDividerLocation());
// expand back from full left
buttonRight.push();
assertEquals("Expandable Back to Original from Left",
initDividerLocation, splitPane.getDividerLocation());
// expand all the way right
buttonRight.push();
assertEquals("Expandable Right",
splitPane.getWidth() - splitPane.getDividerSize() - right,
splitPane.getDividerLocation());
// Click to move back from right expansion
buttonLeft.push();
assertEquals("Expandable Back to Original from Right",
initDividerLocation, splitPane.getDividerLocation());
}
// Test for case where one touch expandable is disabled
if (!oneTouch) {
if (checkBox.isSelected()) {
// uncheck
checkBox.doClick();
}
assertFalse("One Touch Expandable Off", splitPane.isOneTouchExpandable());
}
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo;
import static com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo.*;
import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.ContainerOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JRadioButtonOperator;
import org.netbeans.jemmy.operators.JTabbedPaneOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 TabbedPaneDemo by iterating through tab placement
* positions, opening each tab and verifying the the tab gets selected.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo
* @run testng TabbedPaneDemoTest
*/
public class TabbedPaneDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(TabbedPaneDemo.class.getCanonicalName()).startApplication();
JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
for (String tp : new String[]{TOP, LEFT, BOTTOM, RIGHT}) {
testTabs(mainFrame, tp);
}
});
}
public void testTabs(JFrameOperator mainFrame, String tabPlacement) throws Exception {
ContainerOperator<?> rbCont = getLabeledContainerOperator(mainFrame, TAB_PLACEMENT);
new JRadioButtonOperator(rbCont, tabPlacement).doClick();
final String[] tabTitles = new String[]{CAMILLE, MIRANDA, EWAN, BOUNCE};
for (int i = 0; i < tabTitles.length; i++) {
String pageTitle = tabTitles[i];
JTabbedPaneOperator tabOperator = new JTabbedPaneOperator(mainFrame);
tabOperator.selectPage(pageTitle);
assertEquals("Selected tab is selected", i, tabOperator.getSelectedIndex());
}
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.textfield.JHistoryTextField;
import com.sun.swingset3.demos.textfield.TextFieldDemo;
import static com.sun.swingset3.demos.textfield.TextFieldDemo.*;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import javax.swing.JFormattedTextField;
import static org.jemmy2ext.JemmyExt.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.QueueTool;
import org.netbeans.jemmy.operators.ContainerOperator;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.JPasswordFieldOperator;
import org.netbeans.jemmy.operators.JTextFieldOperator;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 TextFieldDemo by entering text in each field and
* checking that app reacts accordingly.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.textfield.TextFieldDemo
* @run testng TextFieldDemoTest
*/
public class TextFieldDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(TextFieldDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
historyTextField(frame);
dateTextField(frame);
passwordField(frame);
});
}
private void historyTextField(JFrameOperator jfo) throws Exception {
JTextFieldOperator jtfo = new JTextFieldOperator(jfo, new ByClassChooser(JHistoryTextField.class));
jtfo.typeText("cat");
jtfo.pressKey(KeyEvent.VK_DOWN);
jtfo.pressKey(KeyEvent.VK_DOWN);
jtfo.pressKey(KeyEvent.VK_ENTER);
final String expectedValue = "category";
jtfo.waitText(expectedValue);
assertEquals("Select History Item", expectedValue, jtfo.getText());
}
public void dateTextField(JFrameOperator jfo) throws Exception {
JTextFieldOperator jtfo = new JTextFieldOperator(jfo,
new ByClassChooser(JFormattedTextField.class));
ContainerOperator<?> containerOperator = new ContainerOperator<>(jtfo.getParent());
JButtonOperator jbo = new JButtonOperator(containerOperator, GO);
JLabelOperator dowLabel = new JLabelOperator(containerOperator);
Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
// Check default date Day of the Week
jbo.push();
assertEquals("Default DOW",
calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH),
dowLabel.getText());
// Check Custom Day of the Week
calendar.set(2012, 9, 11); // Represents "Oct 11, 2012"
Date date = calendar.getTime();
String dateString = jtfo.getQueueTool().invokeAndWait(
new QueueTool.QueueAction<String>("Formatting the value using JFormattedTextField formatter") {
@Override
public String launch() throws Exception {
return ((JFormattedTextField) jtfo.getSource()).getFormatter().valueToString(date);
}
});
System.out.println("dateString = " + dateString);
jtfo.enterText(dateString);
jbo.push();
assertEquals("Custom DOW", "Thursday", dowLabel.getText());
}
public void passwordField(JFrameOperator jfo) throws Exception {
JPasswordFieldOperator password1 = new JPasswordFieldOperator(jfo, 0);
JPasswordFieldOperator password2 = new JPasswordFieldOperator(jfo, 1);
password1.typeText("password");
password2.typeText("password");
// Check Matching Passwords
assertEquals("Matching Passwords", Color.green, password1.getBackground());
assertEquals("Matching Passwords", Color.green, password2.getBackground());
// Check non-matching passwords
password2.typeText("passwereertegrs");
assertEquals("Non-Matching Passwords", Color.white, password1.getBackground());
assertEquals("Non-Matching Passwords", Color.white, password2.getBackground());
}
}

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.demos.togglebutton.DirectionPanel;
import com.sun.swingset3.demos.togglebutton.LayoutControlPanel;
import com.sun.swingset3.demos.togglebutton.ToggleButtonDemo;
import static com.sun.swingset3.demos.togglebutton.ToggleButtonDemo.*;
import java.util.function.BiFunction;
import org.jemmy2ext.JemmyExt.ByClassChooser;
import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR;
import static org.jemmy2ext.JemmyExt.getBorderTitledJPanelOperator;
import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.ComponentChooser;
import org.netbeans.jemmy.operators.ContainerOperator;
import org.netbeans.jemmy.operators.JCheckBoxOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JRadioButtonOperator;
import org.netbeans.jemmy.operators.JTabbedPaneOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 ToggleButtonDemo by toggling each radio button,
* each checkbox and each location of the direction dial toggle.
* It verifies initial selected values for all the elements and checks
* that those change upon clicking. When toggling radio buttons it
* verifies that other radio buttons in the same group are not longer
* selected.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.togglebutton.ToggleButtonDemo
* @run testng ToggleButtonDemoTest
*/
public class ToggleButtonDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(ToggleButtonDemo.class.getCanonicalName()).startApplication();
JFrameOperator mainFrame = new JFrameOperator(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
JTabbedPaneOperator tabPane = new JTabbedPaneOperator(mainFrame);
// Radio Button Toggles
testRadioButtons(getBorderTitledJPanelOperator(mainFrame, TEXT_RADIO_BUTTONS), 3, null);
testRadioButtons(getBorderTitledJPanelOperator(mainFrame, IMAGE_RADIO_BUTTONS), 3, null);
testRadioButtons(getLabeledContainerOperator(mainFrame, PAD_AMOUNT), 3, (t, i) -> DEFAULT.equals(t));
// switch to the Check Boxes Tab
tabPane.selectPage(CHECK_BOXES);
// Check Box Toggles
ContainerOperator<?> textCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, TEXT_CHECKBOXES);
testCheckBox(textCheckBoxesJPanel, CHECK1, false);
testCheckBox(textCheckBoxesJPanel, CHECK2, false);
testCheckBox(textCheckBoxesJPanel, CHECK3, false);
ContainerOperator<?> imageCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, IMAGE_CHECKBOXES);
testCheckBox(imageCheckBoxesJPanel, CHECK1, false);
testCheckBox(imageCheckBoxesJPanel, CHECK2, false);
testCheckBox(imageCheckBoxesJPanel, CHECK3, false);
ContainerOperator<?> displayOptionsContainer = getLabeledContainerOperator(mainFrame, DISPLAY_OPTIONS);
testCheckBox(displayOptionsContainer, PAINT_BORDER, false);
testCheckBox(displayOptionsContainer, PAINT_FOCUS, true);
testCheckBox(displayOptionsContainer, ENABLED, true);
testCheckBox(displayOptionsContainer, CONTENT_FILLED, true);
// Direction Button Toggles
testToggleButtons(mainFrame);
});
}
/**
* The interface is invoked for each radio button providing its name and
* index and it should return whether the radio button has to be selected.
*/
private static interface SelectedRadioButton extends BiFunction<String, Integer, Boolean> {
}
/**
* Tests a group of radio buttons
*
* @param parent container containing the buttons
* @param radioButtonCount number of radio buttons
* @param selectedRadioButton initial selected radio button
*/
private void testRadioButtons(ContainerOperator<?> parent, int radioButtonCount, SelectedRadioButton selectedRadioButton) {
JRadioButtonOperator[] jrbo = new JRadioButtonOperator[radioButtonCount];
for (int i = 0; i < radioButtonCount; i++) {
jrbo[i] = new JRadioButtonOperator(parent, i);
if (selectedRadioButton != null && selectedRadioButton.apply(jrbo[i].getText(), i)) {
assertTrue("Radio Button " + i + " is initially selected", jrbo[i].isSelected());
} else {
assertFalse("Radio Button " + i + " is initially not selected", jrbo[i].isSelected());
}
}
for (int i = 0; i < radioButtonCount; i++) {
jrbo[i].doClick();
assertTrue("Radio Button " + i + " is selected", jrbo[i].isSelected());
for (int j = 0; j < radioButtonCount; j++) {
if (i != j) {
assertFalse("Radio Button " + j + " is not selected", jrbo[j].isSelected());
}
}
}
}
/**
* Will change the state of the CheckBox then change back to initial state.
*
* @param parent
* @param text
* @param expectedValue
* @throws Exception
*/
private void testCheckBox(ContainerOperator<?> parent, String text, boolean expectedValue) {
parent.setComparator(EXACT_STRING_COMPARATOR);
JCheckBoxOperator jcbo = new JCheckBoxOperator(parent, text);
assertEquals("Initial selection state of the checkbox '" + text + "'", expectedValue, jcbo.isSelected());
// click check box (toggle the state)
jcbo.doClick();
assertEquals("Selection state of the checkbox '" + text + "' after click", !expectedValue, jcbo.isSelected());
if (jcbo.isSelected()) {
// toggle back to not-selected state
jcbo.doClick();
assertFalse("Check Box '" + text + "' is not selected", jcbo.isSelected());
} else {
// toggle back to selected state
jcbo.doClick();
assertTrue("Check Box '" + text + "' is selected", jcbo.isSelected());
}
}
/*
* testDirectionRadioButtons(JFrameOperator) will toggle each position of
* the direction radio button panels
*/
private void testToggleButtons(JFrameOperator jfo) {
ComponentChooser directionPanelChooser = new ByClassChooser(DirectionPanel.class);
String text_Position = LayoutControlPanel.TEXT_POSITION;
ContainerOperator<?> textPositionContainer = getLabeledContainerOperator(jfo, text_Position);
ContainerOperator<?> directionPanelOperator = new ContainerOperator<>(textPositionContainer, directionPanelChooser);
testRadioButtons(directionPanelOperator, 9, (t, i) -> i == 5);
// Unfortunately, both directionPanels are in the same parent container
// so we have to use indexes here.
// There is no guarantee that if the UI changes, the code would be still
// valid in terms of which directionPanel is checked first. However, it
// does guarantee that two different directionPanels are checked.
String content_Alignment = LayoutControlPanel.CONTENT_ALIGNMENT;
ContainerOperator<?> contentAlignmentContainer = getLabeledContainerOperator(jfo, content_Alignment);
ContainerOperator<?> directionPanelOperator2 = new ContainerOperator<>(contentAlignmentContainer, directionPanelChooser,
contentAlignmentContainer.getSource() == textPositionContainer.getSource() ? 1 : 0);
testRadioButtons(directionPanelOperator2, 9, (t, i) -> i == 4);
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.tree.TreeDemo;
import static com.sun.swingset3.demos.tree.TreeDemo.DEMO_TITLE;
import javax.swing.tree.TreePath;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JTreeOperator;
import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 TreeDemo by expanding all collapsed nodes in the
* tree and then collapsing all the expanded nodes in the tree. It
* verifies the number of nodes expanded, number of nodes collapsed and
* number of rows in the tree in the begininng, after expanding and
* after collapsing the nodes. It also checks that the tree grows
* vertically (as ScrollPane allows it).
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.tree.TreeDemo
* @run testng TreeDemoTest
*/
public class TreeDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(TreeDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
JTreeOperator tree = new JTreeOperator(frame);
assertEquals("Initial number of rows in the tree", 4, tree.getRowCount());
int initialTreeHeight = tree.getHeight();
// expand all nodes
int expandsCount = 0;
for (int i = 0; i < tree.getRowCount(); i++) {
TreePath tp = tree.getPathForRow(i);
if (tree.getChildCount(tp) > 0 && !tree.isExpanded(tp)) {
tree.expandRow(i);
expandsCount++;
}
}
assertEquals("Number of rows expanded", 75, expandsCount);
assertEquals("Number of rows in the tree after expanding all of them",
616, tree.getRowCount());
int expandedTreeHeight = tree.getHeight();
assertTrue("Expanded tree height has increased, current "
+ expandedTreeHeight + " > initial " + initialTreeHeight,
expandedTreeHeight > initialTreeHeight);
// collapse all nodes
int collapsesCount = 0;
for (int i = tree.getRowCount() - 1; i >= 0; i--) {
TreePath tp = tree.getPathForRow(i);
if (tree.getChildCount(tp) > 0 && tree.isExpanded(tp)) {
tree.collapseRow(i);
collapsesCount++;
}
}
assertEquals("Number of rows collapsed", 76, collapsesCount);
assertEquals("Number of rows in the tree after collapsing all of them",
1, tree.getRowCount());
int collapsedTreeHeight = tree.getHeight();
assertTrue("Collpased tree height is not longer than initial, "
+ "current " + collapsedTreeHeight + " <= initial "
+ initialTreeHeight,
collapsedTreeHeight <= initialTreeHeight);
});
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.swingset3.demos.window.WindowDemo;
import static com.sun.swingset3.demos.window.WindowDemo.*;
import static org.jemmy2ext.JemmyExt.*;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
import org.netbeans.jemmy.ClassReference;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.WindowOperator;
/*
* @test
* @key headful
* @summary Verifies SwingSet3 WindowDemo by checking that separate JWindow is
* shown, it contains predefined label and no new windows are opened
* when the "Show JWindow..." button is clicked.
*
* @library /sanity/client/lib/jemmy/src
* @library /sanity/client/lib/Jemmy2Ext/src
* @library /sanity/client/lib/SwingSet3/src
* @build org.jemmy2ext.JemmyExt
* @build com.sun.swingset3.demos.window.WindowDemo
* @run testng WindowDemoTest
*/
public class WindowDemoTest {
@Test
public void test() throws Exception {
captureDebugInfoOnFail(() -> {
new ClassReference(WindowDemo.class.getCanonicalName()).startApplication();
JFrameOperator frame = new JFrameOperator();
assertEquals("Only one JWindow is shown", 1, getJWindowCount());
WindowOperator window = new WindowOperator(getJWindow());
assertTrue("JFrame is showing", frame.isShowing());
assertFalse("JFrame is not iconified", isIconified(frame));
assertTrue("JWindow is showing", window.isShowing());
final String labelText = I_HAVE_NO_SYSTEM_BORDER;
JLabelOperator jLabelOperator = new JLabelOperator(window, labelText);
assertEquals("JWindow contains the label with corresponding text", labelText, jLabelOperator.getText());
new JButtonOperator(frame, SHOW_J_WINDOW).push();
assertEquals("Only one JWindow is shown", 1, getJWindowCount());
});
}
}

View File

@ -0,0 +1,24 @@
# This file identifies the root of the test-suite hierarchy.
# It also contains test-suite configuration information.
# The list of keywords supported in the entire test suite. The
# "intermittent" keyword marks tests known to fail intermittently.
# The "randomness" keyword marks tests using randomness with test
# cases differing from run to run. (A test using a fixed random seed
# would not count as "randomness" by this definition.) Extra care
# should be taken to handle test failures of intermittent or
# randomness tests.
#
# A "headful" test requires a graphical environment to meaningfully
# run. Tests that are not headful are "headless."
keys=screenshots
# Tests that must run in othervm mode
othervm.dirs=sanity/client/SwingSet
# Tests that cannot run concurrently
exclusiveAccess.dirs=sanity/client/SwingSet
# Tests using jtreg 4.1 b13 features
requiredVersion=4.1 b13

View File

@ -0,0 +1,14 @@
# This file contains test-suite configuration information related to this portion
# of the test suite.
#
# A "screenshots" test requires a 100% headful graphical environment
# as they rely on Robot to take screenshots and move mouse.
# The list of keywords supported in this part of the test suite
keys=screenshots
# Tests that cannot run concurrently
exclusiveAccess.dirs=SwingSet
# Tests require jtreg 4.1 b13 features
#requiredVersion=4.1 b13

View File

@ -0,0 +1,614 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.jemmy2ext;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Window;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.IntStream;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.TitledBorder;
import org.netbeans.jemmy.ComponentChooser;
import org.netbeans.jemmy.DefaultCharBindingMap;
import org.netbeans.jemmy.QueueTool;
import org.netbeans.jemmy.TimeoutExpiredException;
import org.netbeans.jemmy.Waitable;
import org.netbeans.jemmy.Waiter;
import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
import org.netbeans.jemmy.image.StrictImageComparator;
import org.netbeans.jemmy.operators.ComponentOperator;
import org.netbeans.jemmy.operators.ContainerOperator;
import org.netbeans.jemmy.operators.FrameOperator;
import org.netbeans.jemmy.operators.JButtonOperator;
import org.netbeans.jemmy.operators.JFrameOperator;
import org.netbeans.jemmy.operators.JLabelOperator;
import org.netbeans.jemmy.operators.Operator;
import org.netbeans.jemmy.util.Dumper;
import org.netbeans.jemmy.util.PNGEncoder;
import static org.testng.AssertJUnit.*;
/**
* This class solves two tasks: 1. It adds functionality that is missing in
* Jemmy 2. It references all the Jemmy API that is needed by tests so that they
* can just @build JemmyExt class and do not worry about Jemmy
*
* @author akouznet
*/
public class JemmyExt {
/**
* Statically referencing all the classes that are needed by tests so that
* they're compiled by jtreg
*/
static final Class<?>[] DEPENDENCIES = {
JSpinnerDriver.class,
DefaultCharBindingMap.class
};
public static void assertNotBlack(BufferedImage image) {
int w = image.getWidth();
int h = image.getHeight();
try {
assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
-> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
));
} catch (Throwable t) {
save(image, "allPixelsAreBlack.png");
throw t;
}
}
public static void waitArmed(JButtonOperator button) {
button.waitState(new ComponentChooser() {
@Override
public boolean checkComponent(Component comp) {
return isArmed(button);
}
@Override
public String getDescription() {
return "Button is armed";
}
});
}
public static boolean isArmed(JButtonOperator button) {
return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isArmed()") {
@Override
public Boolean launch() throws Exception {
return ((JButton) button.getSource()).getModel().isArmed();
}
});
}
public static void waitPressed(JButtonOperator button) {
button.waitState(new ComponentChooser() {
@Override
public boolean checkComponent(Component comp) {
return isPressed(button);
}
@Override
public String getDescription() {
return "Button is pressed";
}
});
}
public static boolean isPressed(JButtonOperator button) {
return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isPressed()") {
@Override
public Boolean launch() throws Exception {
return ((JButton) button.getSource()).getModel().isPressed();
}
});
}
public static void assertEquals(String string, StrictImageComparator comparator, BufferedImage expected, BufferedImage actual) {
try {
assertTrue(string, comparator.compare(expected, actual));
} catch (Error err) {
save(expected, "expected.png");
save(actual, "actual.png");
throw err;
}
}
public static void assertNotEquals(String string, StrictImageComparator comparator, BufferedImage notExpected, BufferedImage actual) {
try {
assertFalse(string, comparator.compare(notExpected, actual));
} catch (Error err) {
save(notExpected, "notExpected.png");
save(actual, "actual.png");
throw err;
}
}
public static void save(BufferedImage image, String filename) {
String filepath = filename;
try {
filepath = new File(filename).getCanonicalPath();
System.out.println("Saving screenshot to " + filepath);
BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(filepath));
new PNGEncoder(file, PNGEncoder.COLOR_MODE).encode(image);
} catch (IOException ioe) {
throw new RuntimeException("Failed to save image to " + filepath, ioe);
}
}
public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
operator.waitState(new ComponentChooser() {
private BufferedImage previousImage = null;
private int index = 0;
private final StrictImageComparator sComparator = new StrictImageComparator();
@Override
public boolean checkComponent(Component comp) {
BufferedImage currentImage = capture(rob, operator);
save(currentImage, "waitImageIsStill" + index + ".png");
index++;
boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
previousImage = currentImage;
return compareResult;
}
@Override
public String getDescription() {
return "Image of " + operator + " is still";
}
});
}
private static class ThrowableHolder {
volatile Throwable t;
}
public static void waitFor(String description, RunnableWithException r) throws Exception {
Waiter<Boolean, ThrowableHolder> waiter = new Waiter<>(new Waitable<Boolean, ThrowableHolder>() {
@Override
public Boolean actionProduced(ThrowableHolder obj) {
try {
r.run();
return true;
} catch (Throwable t) {
obj.t = t;
return null;
}
}
@Override
public String getDescription() {
return description;
}
});
ThrowableHolder th = new ThrowableHolder();
try {
waiter.waitAction(th);
} catch (TimeoutExpiredException tee) {
Throwable t = th.t;
if (t != null) {
t.addSuppressed(tee);
if (t instanceof Exception) {
throw (Exception) t;
} else if (t instanceof Error) {
throw (Error) t;
} else if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new IllegalStateException("Unexpected exception type", t);
}
}
}
}
public static BufferedImage capture(Robot rob, ComponentOperator operator) {
Rectangle boundary = new Rectangle(operator.getLocationOnScreen(),
operator.getSize());
return rob.createScreenCapture(boundary);
}
/**
* Wraps the test code so that in case of any failure as much information as
* possible is captured
*
* @param r test code Runnable
* @throws Exception whatever exception the test may throw
*/
public static void captureDebugInfoOnFail(RunnableWithException r) throws Exception {
// TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed
try {
r.run();
System.out.println("TEST PASSED");
} catch (Throwable t) {
captureAll();
throw t;
}
}
/**
* This is a helper class which allows to catch throwables thrown in other
* threads and throw them in the main test thread
*/
public static class MultiThreadedTryCatch {
private final List<Throwable> throwables
= Collections.synchronizedList(new ArrayList<>());
/**
* Throws registered throwables. If the list of the registered
* throwables is not empty, it re-throws the first throwable in the list
* adding all others into its suppressed list. Can be used in any
* thread.
*
* @throws Exception
*/
public void throwRegistered() throws Exception {
Throwable root = null;
synchronized (throwables) {
if (!throwables.isEmpty()) {
root = throwables.remove(0);
while (!throwables.isEmpty()) {
root.addSuppressed(throwables.remove(0));
}
}
}
if (root != null) {
if (root instanceof Error) {
throw (Error) root;
} else if (root instanceof Exception) {
throw (Exception) root;
} else {
throw new AssertionError("Unexpected exception type: " + root.getClass() + " (" + root + ")");
}
}
}
/**
* Registers a throwable and adds it to the list of throwables. Can be
* used in any thread.
*
* @param t
*/
public void register(Throwable t) {
t.printStackTrace();
throwables.add(t);
}
/**
* Registers a throwable and adds it as the first item of the list of
* catched throwables.
*
* @param t
*/
public void registerRoot(Throwable t) {
t.printStackTrace();
throwables.add(0, t);
}
}
/**
* Trying to capture as much information as possible. Currently it includes
* full dump and a screenshot of the whole screen.
*/
public static void captureAll() {
PNGEncoder.captureScreen("failure.png", PNGEncoder.COLOR_MODE);
try {
Dumper.dumpAll("dumpAll.xml");
} catch (FileNotFoundException ex) {
Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
}
captureWindows();
}
/**
* Captures each showing window image using Window.paint() method.
*/
private static void captureWindows() {
try {
EventQueue.invokeAndWait(() -> {
Window[] windows = Window.getWindows();
int index = 0;
for (Window w : windows) {
if (!w.isShowing()) {
continue;
}
BufferedImage img = new BufferedImage(w.getWidth(), w.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
w.paint(g);
g.dispose();
try {
ImageIO.write(img, "png", new File("window" + index++ + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (InterruptedException | InvocationTargetException ex) {
Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static interface RunnableWithException {
public void run() throws Exception;
}
public static void waitIsFocused(JFrameOperator jfo) {
jfo.waitState(new ComponentChooser() {
@Override
public boolean checkComponent(Component comp) {
return jfo.isFocused();
}
@Override
public String getDescription() {
return "JFrame is focused";
}
});
}
public static int getJWindowCount() {
return new QueueTool().invokeAndWait(new QueueTool.QueueAction<Integer>(null) {
@Override
public Integer launch() throws Exception {
Window[] windows = Window.getWindows();
int windowCount = 0;
for (Window w : windows) {
if (w.getClass().equals(JWindow.class)) {
windowCount++;
}
}
return windowCount;
}
});
}
public static JWindow getJWindow() {
return getJWindow(0);
}
public static JWindow getJWindow(int index) {
return new QueueTool().invokeAndWait(new QueueTool.QueueAction<JWindow>(null) {
@Override
public JWindow launch() throws Exception {
Window[] windows = Window.getWindows();
int windowIndex = 0;
for (Window w : windows) {
if (w.getClass().equals(JWindow.class)) {
if (windowIndex == index) {
return (JWindow) w;
}
windowIndex++;
}
}
return null;
}
});
}
public static boolean isIconified(FrameOperator frameOperator) {
return frameOperator.getQueueTool().invokeAndWait(new QueueTool.QueueAction<Boolean>("Frame is iconified") {
@Override
public Boolean launch() throws Exception {
return (((Frame) frameOperator.getSource()).getState() & Frame.ICONIFIED) != 0;
}
});
}
public static final Operator.DefaultStringComparator EXACT_STRING_COMPARATOR
= new Operator.DefaultStringComparator(true, true);
/**
* Finds a label with the exact labelText and returns the operator for its
* parent container.
*
* @param container
* @param labelText
* @return
*/
public static ContainerOperator<?> getLabeledContainerOperator(ContainerOperator<?> container, String labelText) {
container.setComparator(EXACT_STRING_COMPARATOR);
JLabelOperator jLabelOperator = new JLabelOperator(container, labelText);
assert labelText.equals(jLabelOperator.getText());
return new ContainerOperator<>(jLabelOperator.getParent());
}
/**
* Finds a JPanel with exact title text.
*
* @param container
* @param titleText
* @return
*/
public static ContainerOperator<?> getBorderTitledJPanelOperator(ContainerOperator<?> container, String titleText) {
return new ContainerOperator<>(container, new JPanelByBorderTitleFinder(titleText, EXACT_STRING_COMPARATOR));
}
public static final QueueTool QUEUE_TOOL = new QueueTool();
/**
* Allows to find JPanel by the title text in its border.
*/
public static class JPanelByBorderTitleFinder implements ComponentChooser {
String titleText;
Operator.StringComparator comparator;
/**
* @param titleText title text pattern
* @param comparator specifies string comparison algorithm.
*/
public JPanelByBorderTitleFinder(String titleText, Operator.StringComparator comparator) {
this.titleText = titleText;
this.comparator = comparator;
}
/**
* @param titleText title text pattern
*/
public JPanelByBorderTitleFinder(String titleText) {
this(titleText, Operator.getDefaultStringComparator());
}
@Override
public boolean checkComponent(Component comp) {
assert EventQueue.isDispatchThread();
if (comp instanceof JPanel) {
return checkBorder(((JPanel) comp).getBorder());
}
return false;
}
public boolean checkBorder(Border border) {
if (border instanceof TitledBorder) {
String title = ((TitledBorder) border).getTitle();
return comparator.equals(title, titleText);
} else if (border instanceof CompoundBorder) {
CompoundBorder compoundBorder = (CompoundBorder) border;
return checkBorder(compoundBorder.getInsideBorder()) || checkBorder(compoundBorder.getOutsideBorder());
} else {
return false;
}
}
@Override
public String getDescription() {
return ("JPanel with border title text \"" + titleText + "\" with comparator " + comparator);
}
}
public static class ByClassSimpleNameChooser implements ComponentChooser {
private final String className;
public ByClassSimpleNameChooser(String className) {
this.className = className;
}
@Override
public boolean checkComponent(Component comp) {
return comp.getClass().getSimpleName().equals(className);
}
@Override
public String getDescription() {
return "Component with the simple class name of " + className;
}
}
public static class ByClassChooser implements ComponentChooser {
private final Class<?> clazz;
public ByClassChooser(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public boolean checkComponent(Component comp) {
return comp.getClass().equals(clazz);
}
@Override
public String getDescription() {
return "Component with the class of " + clazz;
}
}
public static class ByToolTipChooser implements ComponentChooser {
private final String tooltip;
public ByToolTipChooser(String tooltip) {
if (tooltip == null) {
throw new NullPointerException("Tooltip cannot be null");
}
this.tooltip = tooltip;
}
@Override
public boolean checkComponent(Component comp) {
return (comp instanceof JComponent)
? tooltip.equals(((JComponent) comp).getToolTipText())
: false;
}
@Override
public String getDescription() {
return "JComponent with the tooltip '" + tooltip + "'";
}
}
@SuppressWarnings(value = "unchecked")
public static <R, O extends Operator, S extends Component> R getUIValue(O operator, Function<S, R> getter) {
return operator.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<R>("getting UI value through the queue using " + getter) {
@Override
public R launch() throws Exception {
return getter.apply((S) operator.getSource());
}
});
}
}

View File

@ -0,0 +1,4 @@
This content of this src folder was originally taken from SwingSet3 demo project: https://java.net/projects/swingset3/.
Then it was modified to increase testability and remove extra content and extra dependencies.
Do NOT modify files in it.

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.swingset3;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Annotation type for specifying meta-data about Demo
*
* @author aim
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface DemoProperties {
String value(); // Name
String category();
String description();
String iconFile() default "";
String[] sourceFiles() default "";
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.swingset3.demos;
import java.awt.*;
import java.net.URI;
import java.io.IOException;
import javax.swing.*;
/**
* @author Pavel Porvatov
*/
public class DemoUtilities {
private DemoUtilities() {
// Hide constructor
}
public static void setToplevelLocation(Window toplevel, Component component,
int relativePosition) {
Rectangle compBounds = component.getBounds();
// Convert component location to screen coordinates
Point p = new Point();
SwingUtilities.convertPointToScreen(p, component);
int x;
int y;
// Set frame location to be centered on panel
switch (relativePosition) {
case SwingConstants.NORTH: {
x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
y = p.y - toplevel.getHeight();
break;
}
case SwingConstants.EAST: {
x = p.x + compBounds.width;
y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
break;
}
case SwingConstants.SOUTH: {
x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
y = p.y + compBounds.height;
break;
}
case SwingConstants.WEST: {
x = p.x - toplevel.getWidth();
y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
break;
}
case SwingConstants.NORTH_EAST: {
x = p.x + compBounds.width;
y = p.y - toplevel.getHeight();
break;
}
case SwingConstants.NORTH_WEST: {
x = p.x - toplevel.getWidth();
y = p.y - toplevel.getHeight();
break;
}
case SwingConstants.SOUTH_EAST: {
x = p.x + compBounds.width;
y = p.y + compBounds.height;
break;
}
case SwingConstants.SOUTH_WEST: {
x = p.x - toplevel.getWidth();
y = p.y + compBounds.height;
break;
}
default:
case SwingConstants.CENTER: {
x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
}
}
toplevel.setLocation(x, y);
}
public static boolean browse(URI uri) throws IOException {
// Try using the Desktop api first
try {
Desktop desktop = Desktop.getDesktop();
desktop.browse(uri);
return true;
} catch (SecurityException e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -0,0 +1,231 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.swingset3.demos;
import java.awt.*;
import javax.swing.*;
/**
* JGridPanel
*
* @author Pavel Porvatov
*/
public class JGridPanel extends JPanel {
public static final int DEFAULT_GAP = 5;
public enum Layout {
FIRST,
CENTER,
LAST,
FILL
}
private enum ComponentType {
NO_RESIZABLE,
HORIZONTAL_FILL,
FULL
}
private final int cols;
private int bigCol = -1;
private int bigRow = -1;
private int vGap = -1;
private int hGap = -1;
public JGridPanel(int cols) {
this(cols, -1, -1);
}
public JGridPanel(int cols, int bigCol) {
this(cols, bigCol, -1);
}
public JGridPanel(int cols, int bigCol, int bigRow) {
super(new GridBagLayout());
assert cols > 0;
assert bigCol >= -1 && bigCol < cols;
assert bigRow >= -1;
this.cols = cols;
this.bigCol = bigCol;
this.bigRow = bigRow;
}
public void setVGap(int vGap) {
this.vGap = vGap;
}
public void setHGap(int hGap) {
this.hGap = hGap;
}
public JGridPanel cell() {
return cell(null, getHLayout(null), getVLayout(null), null);
}
public JGridPanel cell(Component component) {
return cell(component, getHLayout(component), getVLayout(component), null);
}
public JGridPanel cell(Component component, Layout hLayout) {
return cell(component, hLayout, getVLayout(component), null);
}
public JGridPanel cell(Component component, Layout hLayout, Layout vLayout) {
return cell(component, hLayout, vLayout, null);
}
public JGridPanel cell(Component component, Insets insets) {
assert insets != null;
return cell(component, getHLayout(component), getVLayout(component), insets);
}
private JGridPanel cell(Component component, Layout hLayout, Layout vLayout, Insets insets) {
int componentCount = getComponentCount();
int x = componentCount % cols;
int y = componentCount / cols;
int weightx = x == bigCol || (bigCol < 0 && hLayout == Layout.FILL) ? 1 : 0;
int weighty = y == bigRow || (bigRow < 0 && vLayout == Layout.FILL) ? 1 : 0;
if (insets == null) {
int topGap = y == 0 ? 0 : vGap;
int leftGap = x == 0 ? 0 : hGap;
insets = new Insets(topGap < 0 ? DEFAULT_GAP : topGap,
leftGap < 0 ? DEFAULT_GAP : leftGap, 0, 0);
}
add(component == null ? createSeparator() : component,
new GridBagConstraints(x, y,
1, 1,
weightx, weighty,
getAnchor(hLayout, vLayout), getFill(hLayout, vLayout),
insets, 0, 0));
return this;
}
public void setComponent(Component component, int col, int row) {
assert col >= 0 && col < cols;
assert row >= 0;
GridBagLayout layout = (GridBagLayout) getLayout();
for (int i = 0; i < getComponentCount(); i++) {
Component oldComponent = getComponent(i);
GridBagConstraints constraints = layout.getConstraints(oldComponent);
if (constraints.gridx == col && constraints.gridy == row) {
remove(i);
add(component == null ? createSeparator() : component, constraints);
validate();
repaint();
return;
}
}
// Cell not found
assert false;
}
private static JComponent createSeparator() {
return new JLabel();
}
private static int getFill(Layout hLayout, Layout vLayout) {
if (hLayout == Layout.FILL) {
return vLayout == Layout.FILL ? GridBagConstraints.BOTH : GridBagConstraints.HORIZONTAL;
}
return vLayout == Layout.FILL ? GridBagConstraints.VERTICAL : GridBagConstraints.NONE;
}
private static ComponentType getComponentType(Component component) {
if (component == null
|| component instanceof JLabel
|| component instanceof JRadioButton
|| component instanceof JCheckBox
|| component instanceof JButton) {
return ComponentType.NO_RESIZABLE;
}
if (component instanceof JComboBox
|| component instanceof JTextField) {
return ComponentType.HORIZONTAL_FILL;
}
return ComponentType.FULL;
}
private static Layout getHLayout(Component component) {
if (getComponentType(component) == ComponentType.NO_RESIZABLE) {
return Layout.FIRST;
} else {
return Layout.FILL;
}
}
private static Layout getVLayout(Component component) {
if (getComponentType(component) == ComponentType.FULL) {
return Layout.FILL;
} else {
return Layout.CENTER;
}
}
private static final int[][] ANCHORS = new int[][]{
{GridBagConstraints.NORTHWEST, GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST},
{GridBagConstraints.WEST, GridBagConstraints.CENTER, GridBagConstraints.EAST},
{GridBagConstraints.SOUTHWEST, GridBagConstraints.SOUTH, GridBagConstraints.SOUTHEAST}
};
private static int getAnchorIndex(Layout layout) {
if (layout == Layout.CENTER) {
return 1;
} else if (layout == Layout.LAST) {
return 2;
} else {
return 0;
}
}
private static int getAnchor(Layout hLayout, Layout vLayout) {
return ANCHORS[getAnchorIndex(vLayout)][getAnchorIndex(hLayout)];
}
public void setBorderEqual(int border) {
setBorder(BorderFactory.createEmptyBorder(border, border, border, border));
}
}

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.swingset3.demos;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
*
* @author aim
*/
//<snip>Create HTML hyperlink
//<snip>Create HTML image hyperlink
public class JHyperlink extends JButton {
private static final BrowseAction defaultBrowseAction = new BrowseAction();
private URI targetURI;
private boolean visited;
private final transient Rectangle viewRect = new Rectangle();
private final transient Rectangle iconRect = new Rectangle();
private final transient Rectangle textRect = new Rectangle();
//remind(aim): lookup colors instead of hardcoding them
private Color normalForeground;
private Color activeForeground;
private Color visitedForeground;
private boolean drawUnderline = true;
static {
UIManager.put("Hyperlink.foreground", Color.blue);
UIManager.put("Hyperlink.activeForeground", Color.red);
UIManager.put("Hyperlink.visitedForeground", new Color(85, 145, 90));
}
/**
* Creates a new instance of JHyperlink
*/
public JHyperlink() {
super();
normalForeground = UIManager.getColor("Hyperlink.foreground");
activeForeground = UIManager.getColor("Hyperlink.activeForeground");
visitedForeground = UIManager.getColor("Hyperlink.visitedForeground");
setBorderPainted(false);
setContentAreaFilled(false);
setForeground(normalForeground);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
setMargin(new Insets(0, 0, 0, 0));
setAction(defaultBrowseAction);
}
/**
* Creates a new instance of JHyperlink
*/
public JHyperlink(String text) {
this();
setText(text); // override the inheritence of the action's name
}
public JHyperlink(String text, String targetURI) throws URISyntaxException {
this(text, new URI(targetURI));
}
public JHyperlink(String text, URI target) {
this(text);
setTarget(target);
}
public JHyperlink(String text, Action action) {
this(text);
setAction(action); // replaces default browse action
setText(text); // override the inheritence of the action's name
}
public JHyperlink(String text, Icon icon) {
this(text);
setIcon(icon);
}
public JHyperlink(Icon icon, String targetURI) throws URISyntaxException {
this(null, icon, targetURI);
}
public JHyperlink(String text, Icon icon, String targetURI) throws URISyntaxException {
this(text, new URI(targetURI));
setIcon(icon);
}
public JHyperlink(String text, Icon icon, URI target) {
this(text);
setIcon(icon);
setTarget(target);
}
public void setTarget(URI target) {
this.targetURI = target;
setToolTipText(target.toASCIIString());
}
public URI getTarget() {
return targetURI;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public boolean isVisited() {
return visited;
}
@Override
public void setForeground(Color foreground) {
normalForeground = foreground;
super.setForeground(foreground);
}
public void setVisitedForeground(Color visited) {
visitedForeground = visited;
}
public void setDrawUnderline(boolean drawUnderline) {
this.drawUnderline = drawUnderline;
}
public boolean getDrawUnderline() {
return drawUnderline;
}
@Override
protected void paintComponent(Graphics g) {
// Set the foreground on the fly to ensure the text is painted
// with the proper color in super.paintComponent
ButtonModel model = getModel();
if (model.isArmed()) {
super.setForeground(activeForeground);
} else if (visited) {
super.setForeground(visitedForeground);
} else {
super.setForeground(normalForeground);
}
super.paintComponent(g);
if (drawUnderline) {
Insets insets = getInsets();
viewRect.x = insets.left;
viewRect.y = insets.top;
viewRect.width = getWidth() - insets.left - insets.right;
viewRect.height = getHeight() - insets.top - insets.bottom;
int baseline = getBaseline(viewRect.width, viewRect.height);
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
textRect.x = textRect.y = textRect.width = textRect.height = 0;
SwingUtilities.layoutCompoundLabel(g.getFontMetrics(), getText(),
getIcon(), getVerticalAlignment(), getHorizontalAlignment(),
getVerticalTextPosition(), getHorizontalTextPosition(),
viewRect, iconRect, textRect, getIconTextGap());
// getBaseline not returning correct results, so workaround for now
if (UIManager.getLookAndFeel().getName().equals("Nimbus")) {
baseline += 7;
} else {
baseline += 3;
}
g.setColor(getForeground());
g.drawLine(textRect.x,
baseline,
textRect.x + textRect.width,
baseline);
}
}
// This action is stateless and hence can be shared across hyperlinks
private static class BrowseAction extends AbstractAction {
public BrowseAction() {
super();
}
@Override
public void actionPerformed(ActionEvent e) {
JHyperlink hyperlink = (JHyperlink) e.getSource();
URI targetURI = hyperlink.getTarget();
if (targetURI != null) {
try {
DemoUtilities.browse(targetURI);
hyperlink.setVisited(true);
} catch (Exception ex) {
ex.printStackTrace();
System.err.println(ex);
}
}
}
}
//</snip>
//</snip>
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.swingset3.demos;
import java.net.URL;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
/**
* @author Pavel Porvatov
*/
public class ResourceManager {
private static final Logger logger = Logger.getLogger(ResourceManager.class.getName());
private final Class<?> demoClass;
// Resource bundle for internationalized and accessible text
private ResourceBundle bundle = null;
public ResourceManager(Class<?> demoClass) {
this.demoClass = demoClass;
String bundleName = demoClass.getPackage().getName() + ".resources." + demoClass.getSimpleName();
try {
bundle = ResourceBundle.getBundle(bundleName);
} catch (MissingResourceException e) {
logger.log(Level.SEVERE, "Couldn't load bundle: " + bundleName);
}
}
public String getString(String key) {
return bundle != null ? bundle.getString(key) : key;
}
public char getMnemonic(String key) {
return (getString(key)).charAt(0);
}
public ImageIcon createImageIcon(String filename, String description) {
String path = "resources/images/" + filename;
URL imageURL = demoClass.getResource(path);
if (imageURL == null) {
logger.log(Level.SEVERE, "unable to access image file: " + path);
return null;
} else {
return new ImageIcon(imageURL, description);
}
}
}

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.swingset3.demos.button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.net.URISyntaxException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.demos.JHyperlink;
/**
*
* @author aim
*/
@DemoProperties(
value = "JButton Demo",
category = "Controls",
description = "Demonstrates the many uses of JButton, Swing's push button component.",
sourceFiles = {
"com/sun/swingset3/demos/button/ButtonDemo.java",
"com/sun/swingset3/demos/JHyperlink.java",
"com/sun/swingset3/demos/button/resources/ButtonDemo.html",
"com/sun/swingset3/demos/button/resources/images/blogs.png",
"com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif",
"com/sun/swingset3/demos/button/resources/images/document-print.png",
"com/sun/swingset3/demos/button/resources/images/earth_day.gif",
"com/sun/swingset3/demos/button/resources/images/earth_night.gif",
"com/sun/swingset3/demos/button/resources/images/edit-find.png",
"com/sun/swingset3/demos/button/resources/images/redbutton.png",
"com/sun/swingset3/demos/button/resources/images/redbutton_dark.png",
"com/sun/swingset3/demos/button/resources/images/redbutton_glow.png"
}
)
public final class ButtonDemo extends JPanel {
public static final String DEMO_TITLE = ButtonDemo.class.getAnnotation(DemoProperties.class).value();
public static final String DO_IT_AGAIN = "Do it again";
public static final String DO_IT = "Do it";
public static final String BUTTON_WITH_TEXT_AND_IMAGE = "button with text and image";
public static final String BUTTON_WITH_BACKGROUND_COLOR = "button with background color";
public static final String GO = "Go";
public static final String FIND = "Find";
public static final String IMAGE_BUTTON = "image button";
public static final String SIMPLE_BUTTON = "simple button";
public static final String GET_MORE_INFO = "Get More Info";
public static final String JAVA_BLOGS_URL = "https://blogs.oracle.com/java/";
public static final String JAVA_SE_URL = "http://www.oracle.com/technetwork/java/javase/overview/index.html";
public static final String BUTTON_WITH_ROLLOVER_IMAGE = "button with rollover image";
public static final String BUTTON_WITH_NO_BORDER = "button with no border";
public static final String CONNECT = "Connect";
public ButtonDemo() {
setToolTipText("Demonstrates JButton, Swing's push button component.");
initComponents();
setOpaque(false);
}
protected void initComponents() {
setLayout(new GridLayout(0, 1));
add(createSimpleButtonPanel());
add(createCreativeButtonPanel());
}
protected JPanel createSimpleButtonPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 8));
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
"Simple Buttons"));
//<snip>Create simple button
final JButton simpleButton = new JButton(DO_IT);
simpleButton.setToolTipText(SIMPLE_BUTTON);
//</snip>
//<snip>Add action listener using anonymous inner class
// This style is useful when the action code is tied to a
// single button instance and it's useful for simplicity
// sake to keep the action code located near the button.
// More global application actions should be implemented
// using Action classes instead.
simpleButton.addActionListener((ActionEvent event) -> {
simpleButton.setText(DO_IT_AGAIN);
// Need to force toplevel to relayout to accommodate new button size
SwingUtilities.getWindowAncestor(simpleButton).validate();
});
//</snip>
simpleButton.putClientProperty("snippetKey", "Create simple button");
panel.add(simpleButton);
//<snip>Create image button
// Image is from the Java Look and Feel Graphics Repository
JButton button = new JButton(new ImageIcon(getClass().
getResource("resources/images/document-print.png")));
button.setToolTipText(IMAGE_BUTTON);
//</snip>
button.putClientProperty("snippetKey", "Create image button");
panel.add(button);
//<snip>Create button with text and image
// Image is from the Java Look and Feel Graphics Repository
button = new JButton(FIND,
new ImageIcon(getClass().
getResource("resources/images/edit-find.png")));
button.setToolTipText(BUTTON_WITH_TEXT_AND_IMAGE);
button.setHorizontalTextPosition(JButton.LEADING);
button.setIconTextGap(6);
//</snip>
button.putClientProperty("snippetKey", "Create button with text and image");
panel.add(button);
//<snip>Create button with background color
button = new JButton(GO);
button.setBackground(Color.green);
button.setContentAreaFilled(true);
button.setOpaque(false);
button.setToolTipText(BUTTON_WITH_BACKGROUND_COLOR);
//</snip>
button.putClientProperty("snippetKey", "Create button with background color");
panel.add(button);
return panel;
}
protected JPanel createCreativeButtonPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 16, 8));
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
"More Interesting Buttons"));
//<snip>Create button with no border
JButton button = new JButton();
button.setText(CONNECT);
button.setIcon(new ImageIcon(getClass().getResource("resources/images/earth_day.gif")));
button.setPressedIcon(new ImageIcon(getClass().getResource("resources/images/earth_night.gif")));
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setVerticalTextPosition(JButton.BOTTOM);
button.setHorizontalTextPosition(JButton.CENTER);
button.setIconTextGap(0);
button.setToolTipText(BUTTON_WITH_NO_BORDER);
//</snip>
button.putClientProperty("snippetKey", "Create button with no border");
panel.add(button);
//<snip>Create image button with rollover image
button = new JButton();
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setIcon(new ImageIcon(getClass().getResource("resources/images/redbutton.png")));
button.setRolloverEnabled(true);
button.setRolloverIcon(new ImageIcon(getClass().getResource("resources/images/redbutton_glow.png")));
button.setPressedIcon(new ImageIcon(getClass().getResource("resources/images/redbutton_dark.png")));
button.setToolTipText(BUTTON_WITH_ROLLOVER_IMAGE);
//</snip>
button.putClientProperty("snippetKey", "Create image button with rollover image");
panel.add(button);
//<snip>Create HTML hyperlink
JHyperlink hyperlink;
try {
hyperlink = new JHyperlink(GET_MORE_INFO, JAVA_SE_URL);
} catch (URISyntaxException use) {
use.printStackTrace();
hyperlink = new JHyperlink(GET_MORE_INFO);
}
//</snip>
hyperlink.putClientProperty("snippetKey", "Create HTML hyperlink");
panel.add(hyperlink);
//<snip>Create HTML image hyperlink
try {
hyperlink = new JHyperlink(
new ImageIcon(getClass().getResource("resources/images/blogs.png")), JAVA_BLOGS_URL);
} catch (URISyntaxException use) {
use.printStackTrace();
}
//</snip>
button.putClientProperty("snippetKey", "Create HTML image hyperlink");
panel.add(hyperlink);
return panel;
}
public static void main(String args[]) {
final ButtonDemo buttonDemo = new ButtonDemo();
javax.swing.SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame(DEMO_TITLE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(buttonDemo);
frame.pack();
frame.setVisible(true);
});
}
}

Some files were not shown because too many files have changed in this diff Show More