This commit is contained in:
Christian Tornqvist 2015-02-04 18:22:46 -08:00
commit edbc932bc7
225 changed files with 10959 additions and 3344 deletions

View file

@ -290,3 +290,4 @@ abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44
bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45 bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45
722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46 722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46
8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47 8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47
b2f9702efbe95527ea3a991474fda23987ff1c5c jdk9-b48

View file

@ -290,3 +290,4 @@ f7c11da0b0481d49cc7a65a453336c108191e821 jdk9-b42
3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45 3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45
12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46 12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46
b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47 b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
0064e246d83f6f9fc245c19b6d05041ecaf4b6d4 jdk9-b48

View file

@ -987,3 +987,26 @@ AC_DEFUN_ONCE([BASIC_TEST_USABILITY_ISSUES],
IS_RECONFIGURE=no IS_RECONFIGURE=no
fi fi
]) ])
# Check for support for specific options in bash
AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS],
[
# Test if bash supports pipefail.
AC_MSG_CHECKING([if bash supports pipefail])
if ${BASH} -c 'set -o pipefail'; then
BASH_ARGS="$BASH_ARGS -o pipefail"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
AC_MSG_CHECKING([if bash supports errexit (-e)])
if ${BASH} -e -c 'true'; then
BASH_ARGS="$BASH_ARGS -e"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
AC_SUBST(BASH_ARGS)
])

View file

@ -46,8 +46,12 @@ endif
BOOT_JDK := $(JDK_IMAGE_DIR) BOOT_JDK := $(JDK_IMAGE_DIR)
# The bootcycle build has a different output directory # The bootcycle build has a different output directory
BUILD_OUTPUT:=@BUILD_OUTPUT@/bootcycle-build OLD_BUILD_OUTPUT:=@BUILD_OUTPUT@
SJAVAC_SERVER_DIR:=$(subst @BUILD_OUTPUT@,$(BUILD_OUTPUT),$(SJAVAC_SERVER_DIR)) BUILD_OUTPUT:=$(OLD_BUILD_OUTPUT)/bootcycle-build
# The HOTSPOT_DIST dir is not defined relative to BUILD_OUTPUT in spec.gmk. Must not
# use space in this patsubst to avoid leading space in HOTSPOT_DIST.
HOTSPOT_DIST:=$(patsubst $(OLD_BUILD_OUTPUT)%,$(BUILD_OUTPUT)%,$(HOTSPOT_DIST))
SJAVAC_SERVER_DIR:=$(patsubst $(OLD_BUILD_OUTPUT)%, $(BUILD_OUTPUT)%, $(SJAVAC_SERVER_DIR))
JAVA_CMD:=$(BOOT_JDK)/bin/java JAVA_CMD:=$(BOOT_JDK)/bin/java
JAVAC_CMD:=$(BOOT_JDK)/bin/javac JAVAC_CMD:=$(BOOT_JDK)/bin/javac

View file

@ -113,6 +113,7 @@ HELP_SETUP_DEPENDENCY_HELP
# Setup tools that requires more complex handling, or that is not needed by the configure script. # Setup tools that requires more complex handling, or that is not needed by the configure script.
BASIC_SETUP_COMPLEX_TOOLS BASIC_SETUP_COMPLEX_TOOLS
BASIC_CHECK_BASH_OPTIONS
# Check if pkg-config is available. # Check if pkg-config is available.
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG

View file

@ -853,6 +853,7 @@ OS_VERSION_MICRO
OS_VERSION_MINOR OS_VERSION_MINOR
OS_VERSION_MAJOR OS_VERSION_MAJOR
PKG_CONFIG PKG_CONFIG
BASH_ARGS
CODESIGN CODESIGN
XATTR XATTR
DSYMUTIL DSYMUTIL
@ -3522,6 +3523,9 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# Check for support for specific options in bash
# #
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -4329,7 +4333,7 @@ TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++"
#CUSTOM_AUTOCONF_INCLUDE #CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks: # Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1420811523 DATE_WHEN_GENERATED=1421247827
############################################################################### ###############################################################################
# #
@ -19609,6 +19613,32 @@ $as_echo "yes" >&6; }
fi fi
# Test if bash supports pipefail.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports pipefail" >&5
$as_echo_n "checking if bash supports pipefail... " >&6; }
if ${BASH} -c 'set -o pipefail'; then
BASH_ARGS="$BASH_ARGS -o pipefail"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports errexit (-e)" >&5
$as_echo_n "checking if bash supports errexit (-e)... " >&6; }
if ${BASH} -e -c 'true'; then
BASH_ARGS="$BASH_ARGS -e"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# Check if pkg-config is available. # Check if pkg-config is available.
@ -27408,8 +27438,8 @@ $as_echo "$as_me: Trying to extract Visual Studio environment variables" >&6;}
# The trailing space for everyone except PATH is no typo, but is needed due # The trailing space for everyone except PATH is no typo, but is needed due
# to trailing \ in the Windows paths. These will be stripped later. # to trailing \ in the Windows paths. These will be stripped later.
$ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE $ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE\;$include \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB\;$lib \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE $ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE $ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE $ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE

View file

@ -78,6 +78,11 @@ endif
OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@ OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
OUTPUT_SYNC:=@OUTPUT_SYNC@ OUTPUT_SYNC:=@OUTPUT_SYNC@
# Override the shell with bash
BASH:=@BASH@
BASH_ARGS:=@BASH_ARGS@
SHELL:=$(BASH) $(BASH_ARGS)
# The "human readable" name of this configuration # The "human readable" name of this configuration
CONF_NAME:=@CONF_NAME@ CONF_NAME:=@CONF_NAME@
@ -243,7 +248,7 @@ MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/makesupport
HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot
JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk
IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/testmake TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
HOTSPOT_DIST=@HOTSPOT_DIST@ HOTSPOT_DIST=@HOTSPOT_DIST@
@ -495,7 +500,6 @@ endif
# Tools adhering to a minimal and common standard of posix compliance. # Tools adhering to a minimal and common standard of posix compliance.
AWK:=@AWK@ AWK:=@AWK@
BASENAME:=@BASENAME@ BASENAME:=@BASENAME@
BASH:=@BASH@
CAT:=@CAT@ CAT:=@CAT@
CCACHE:=@CCACHE@ CCACHE:=@CCACHE@
# CD is going away, but remains to cater for legacy makefiles. # CD is going away, but remains to cater for legacy makefiles.

View file

@ -290,3 +290,4 @@ e27c725d6c9d155667b35255f442d4ceb8c3c084 jdk9-b40
9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45 9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45
326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46 326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46
ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47 ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48

View file

@ -450,3 +450,4 @@ c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45 5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46 a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47 3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48

View file

@ -74,6 +74,12 @@ CFLAGS += -D_REENTRANT
# no xlc counterpart for -fcheck-new # no xlc counterpart for -fcheck-new
# CFLAGS += -fcheck-new # CFLAGS += -fcheck-new
# We need to define this on the command line if we want to use the the
# predefined format specifiers from "inttypes.h". Otherwise system headrs
# can indirectly include inttypes.h before we define __STDC_FORMAT_MACROS
# in globalDefinitions.hpp
CFLAGS += -D__STDC_FORMAT_MACROS
ARCHFLAG = -q64 ARCHFLAG = -q64
CFLAGS += $(ARCHFLAG) CFLAGS += $(ARCHFLAG)

View file

@ -1,16 +0,0 @@
#!/bin/sh
# If we're cross compiling use that path for nm
if [ "$CROSS_COMPILE_ARCH" != "" ]; then
NM=$ALT_COMPILER_PATH/nm
else
NM=nm
fi
$NM --defined-only $* \
| awk '{
if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";"
if ($3 ~ /^UseSharedSpaces$/) print "\t" $3 ";"
if ($3 ~ /^_ZN9Arguments17SharedArchivePathE$/) print "\t" $3 ";"
}' \
| sort -u

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -239,8 +239,14 @@ mapfile_reorder : mapfile $(REORDERFILE)
rm -f $@ rm -f $@
cat $^ > $@ cat $^ > $@
VMDEF_PAT = ^_ZTV
VMDEF_PAT := ^gHotSpotVM|$(VMDEF_PAT)
VMDEF_PAT := ^UseSharedSpaces$$|$(VMDEF_PAT)
VMDEF_PAT := ^_ZN9Arguments17SharedArchivePathE$$|$(VMDEF_PAT)
vm.def: $(Res_Files) $(Obj_Files) vm.def: $(Res_Files) $(Obj_Files)
sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@ $(QUIETLY) $(NM) --defined-only $(Obj_Files) | sort -k3 -u | \
awk '$$3 ~ /$(VMDEF_PAT)/ { print "\t" $$3 ";" }' > $@
mapfile_ext: mapfile_ext:
rm -f $@ rm -f $@

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. // Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// //
// This code is free software; you can redistribute it and/or modify it // This code is free software; you can redistribute it and/or modify it
@ -2996,7 +2996,7 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
%} %}
enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{ enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
Label Lword_loop, Lpost_word, Lchar, Lchar_loop, Ldone; Label Lchar, Lchar_loop, Ldone;
MacroAssembler _masm(&cbuf); MacroAssembler _masm(&cbuf);
Register str1_reg = reg_to_register_object($str1$$reg); Register str1_reg = reg_to_register_object($str1$$reg);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -6194,7 +6194,7 @@ void MacroAssembler::string_indexofC8(Register str1, Register str2,
ShortBranchVerifier sbv(this); ShortBranchVerifier sbv(this);
assert(UseSSE42Intrinsics, "SSE4.2 is required"); assert(UseSSE42Intrinsics, "SSE4.2 is required");
// This method uses pcmpestri inxtruction with bound registers // This method uses pcmpestri instruction with bound registers
// inputs: // inputs:
// xmm - substring // xmm - substring
// rax - substring length (elements count) // rax - substring length (elements count)
@ -6355,7 +6355,7 @@ void MacroAssembler::string_indexof(Register str1, Register str2,
// //
assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0"); assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0");
// This method uses pcmpestri inxtruction with bound registers // This method uses pcmpestri instruction with bound registers
// inputs: // inputs:
// xmm - substring // xmm - substring
// rax - substring length (elements count) // rax - substring length (elements count)
@ -6644,7 +6644,6 @@ void MacroAssembler::string_compare(Register str1, Register str2,
// start from first character again because it has aligned address. // start from first character again because it has aligned address.
int stride2 = 16; int stride2 = 16;
int adr_stride = stride << scale; int adr_stride = stride << scale;
int adr_stride2 = stride2 << scale;
assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri"); assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri");
// rax and rdx are used by pcmpestri as elements counters // rax and rdx are used by pcmpestri as elements counters
@ -6743,7 +6742,7 @@ void MacroAssembler::string_compare(Register str1, Register str2,
// inputs: // inputs:
// vec1- substring // vec1- substring
// rax - negative string length (elements count) // rax - negative string length (elements count)
// mem - scaned string // mem - scanned string
// rdx - string length (elements count) // rdx - string length (elements count)
// pcmpmask - cmp mode: 11000 (string compare with negated result) // pcmpmask - cmp mode: 11000 (string compare with negated result)
// + 00 (unsigned bytes) or + 01 (unsigned shorts) // + 00 (unsigned bytes) or + 01 (unsigned shorts)

View file

@ -31,6 +31,7 @@
#include "os_aix.inline.hpp" #include "os_aix.inline.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/perfMemory.hpp" #include "runtime/perfMemory.hpp"
#include "services/memTracker.hpp"
#include "utilities/exceptions.hpp" #include "utilities/exceptions.hpp"
// put OS-includes here // put OS-includes here
@ -196,12 +197,37 @@ static pid_t filename_to_pid(const char* filename) {
return pid; return pid;
} }
// Check if the given statbuf is considered a secure directory for
// the backing store files. Returns true if the directory is considered
// a secure location. Returns false if the statbuf is a symbolic link or
// if an error occurred.
static bool is_statbuf_secure(struct stat *statp) {
if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
// The path represents a link or some non-directory file type,
// which is not what we expected. Declare it insecure.
//
return false;
}
// We have an existing directory, check if the permissions are safe.
if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
// The directory is open for writing and could be subjected
// to a symlink or a hard link attack. Declare it insecure.
return false;
}
// See if the uid of the directory matches the effective uid of the process.
//
if (statp->st_uid != geteuid()) {
// The directory was not created by this user, declare it insecure.
return false;
}
return true;
}
// check if the given path is considered a secure directory for
// Check if the given path is considered a secure directory for
// the backing store files. Returns true if the directory exists // the backing store files. Returns true if the directory exists
// and is considered a secure location. Returns false if the path // and is considered a secure location. Returns false if the path
// is a symbolic link or if an error occurred. // is a symbolic link or if an error occurred.
//
static bool is_directory_secure(const char* path) { static bool is_directory_secure(const char* path) {
struct stat statbuf; struct stat statbuf;
int result = 0; int result = 0;
@ -211,38 +237,276 @@ static bool is_directory_secure(const char* path) {
return false; return false;
} }
// the path exists, now check it's mode // The path exists, see if it is secure.
if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) { return is_statbuf_secure(&statbuf);
// the path represents a link or some non-directory file type, }
// which is not what we expected. declare it insecure.
// // (Taken over from Solaris to support the O_NOFOLLOW case on AIX.)
// Check if the given directory file descriptor is considered a secure
// directory for the backing store files. Returns true if the directory
// exists and is considered a secure location. Returns false if the path
// is a symbolic link or if an error occurred.
static bool is_dirfd_secure(int dir_fd) {
struct stat statbuf;
int result = 0;
RESTARTABLE(::fstat(dir_fd, &statbuf), result);
if (result == OS_ERR) {
return false; return false;
} }
else {
// we have an existing directory, check if the permissions are safe. // The path exists, now check its mode.
// return is_statbuf_secure(&statbuf);
if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) { }
// the directory is open for writing and could be subjected
// to a symlnk attack. declare it insecure.
// // Check to make sure fd1 and fd2 are referencing the same file system object.
return false; static bool is_same_fsobject(int fd1, int fd2) {
struct stat statbuf1;
struct stat statbuf2;
int result = 0;
RESTARTABLE(::fstat(fd1, &statbuf1), result);
if (result == OS_ERR) {
return false;
}
RESTARTABLE(::fstat(fd2, &statbuf2), result);
if (result == OS_ERR) {
return false;
}
if ((statbuf1.st_ino == statbuf2.st_ino) &&
(statbuf1.st_dev == statbuf2.st_dev)) {
return true;
} else {
return false;
}
}
// Helper functions for open without O_NOFOLLOW which is not present on AIX 5.3/6.1.
// We use the jdk6 implementation here.
#ifndef O_NOFOLLOW
// The O_NOFOLLOW oflag doesn't exist before solaris 5.10, this is to simulate that behaviour
// was done in jdk 5/6 hotspot by Oracle this way
static int open_o_nofollow_impl(const char* path, int oflag, mode_t mode, bool use_mode) {
struct stat orig_st;
struct stat new_st;
bool create;
int error;
int fd;
create = false;
if (lstat(path, &orig_st) != 0) {
if (errno == ENOENT && (oflag & O_CREAT) != 0) {
// File doesn't exist, but_we want to create it, add O_EXCL flag
// to make sure no-one creates it (or a symlink) before us
// This works as we expect with symlinks, from posix man page:
// 'If O_EXCL and O_CREAT are set, and path names a symbolic
// link, open() shall fail and set errno to [EEXIST]'.
oflag |= O_EXCL;
create = true;
} else {
// File doesn't exist, and we are not creating it.
return OS_ERR;
} }
} else {
// Lstat success, check if existing file is a link.
if ((orig_st.st_mode & S_IFMT) == S_IFLNK) {
// File is a symlink.
errno = ELOOP;
return OS_ERR;
}
}
if (use_mode == true) {
fd = open(path, oflag, mode);
} else {
fd = open(path, oflag);
}
if (fd == OS_ERR) {
return fd;
}
// Can't do inode checks on before/after if we created the file.
if (create == false) {
if (fstat(fd, &new_st) != 0) {
// Keep errno from fstat, in case close also fails.
error = errno;
::close(fd);
errno = error;
return OS_ERR;
}
if (orig_st.st_dev != new_st.st_dev || orig_st.st_ino != new_st.st_ino) {
// File was tampered with during race window.
::close(fd);
errno = EEXIST;
if (PrintMiscellaneous && Verbose) {
warning("possible file tampering attempt detected when opening %s", path);
}
return OS_ERR;
}
}
return fd;
}
static int open_o_nofollow(const char* path, int oflag, mode_t mode) {
return open_o_nofollow_impl(path, oflag, mode, true);
}
static int open_o_nofollow(const char* path, int oflag) {
return open_o_nofollow_impl(path, oflag, 0, false);
}
#endif
// Open the directory of the given path and validate it.
// Return a DIR * of the open directory.
static DIR *open_directory_secure(const char* dirname) {
// Open the directory using open() so that it can be verified
// to be secure by calling is_dirfd_secure(), opendir() and then check
// to see if they are the same file system object. This method does not
// introduce a window of opportunity for the directory to be attacked that
// calling opendir() and is_directory_secure() does.
int result;
DIR *dirp = NULL;
// No O_NOFOLLOW defined at buildtime, and it is not documented for open;
// so provide a workaround in this case.
#ifdef O_NOFOLLOW
RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
#else
// workaround (jdk6 coding)
RESTARTABLE(::open_o_nofollow(dirname, O_RDONLY), result);
#endif
if (result == OS_ERR) {
// Directory doesn't exist or is a symlink, so there is nothing to cleanup.
if (PrintMiscellaneous && Verbose) {
if (errno == ELOOP) {
warning("directory %s is a symlink and is not secure\n", dirname);
} else {
warning("could not open directory %s: %s\n", dirname, strerror(errno));
}
}
return dirp;
}
int fd = result;
// Determine if the open directory is secure.
if (!is_dirfd_secure(fd)) {
// The directory is not a secure directory.
os::close(fd);
return dirp;
}
// Open the directory.
dirp = ::opendir(dirname);
if (dirp == NULL) {
// The directory doesn't exist, close fd and return.
os::close(fd);
return dirp;
}
// Check to make sure fd and dirp are referencing the same file system object.
if (!is_same_fsobject(fd, dirp->dd_fd)) {
// The directory is not secure.
os::close(fd);
os::closedir(dirp);
dirp = NULL;
return dirp;
}
// Close initial open now that we know directory is secure
os::close(fd);
return dirp;
}
// NOTE: The code below uses fchdir(), open() and unlink() because
// fdopendir(), openat() and unlinkat() are not supported on all
// versions. Once the support for fdopendir(), openat() and unlinkat()
// is available on all supported versions the code can be changed
// to use these functions.
// Open the directory of the given path, validate it and set the
// current working directory to it.
// Return a DIR * of the open directory and the saved cwd fd.
//
static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
// Open the directory.
DIR* dirp = open_directory_secure(dirname);
if (dirp == NULL) {
// Directory doesn't exist or is insecure, so there is nothing to cleanup.
return dirp;
}
int fd = dirp->dd_fd;
// Open a fd to the cwd and save it off.
int result;
RESTARTABLE(::open(".", O_RDONLY), result);
if (result == OS_ERR) {
*saved_cwd_fd = -1;
} else {
*saved_cwd_fd = result;
}
// Set the current directory to dirname by using the fd of the directory.
result = fchdir(fd);
return dirp;
}
// Close the directory and restore the current working directory.
static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
int result;
// If we have a saved cwd change back to it and close the fd.
if (saved_cwd_fd != -1) {
result = fchdir(saved_cwd_fd);
::close(saved_cwd_fd);
}
// Close the directory.
os::closedir(dirp);
}
// Check if the given file descriptor is considered a secure.
static bool is_file_secure(int fd, const char *filename) {
int result;
struct stat statbuf;
// Determine if the file is secure.
RESTARTABLE(::fstat(fd, &statbuf), result);
if (result == OS_ERR) {
if (PrintMiscellaneous && Verbose) {
warning("fstat failed on %s: %s\n", filename, strerror(errno));
}
return false;
}
if (statbuf.st_nlink > 1) {
// A file with multiple links is not expected.
if (PrintMiscellaneous && Verbose) {
warning("file %s has multiple links\n", filename);
}
return false;
} }
return true; return true;
} }
// Return the user name for the given user id.
// return the user name for the given user id
//
// the caller is expected to free the allocated memory.
// //
// The caller is expected to free the allocated memory.
static char* get_user_name(uid_t uid) { static char* get_user_name(uid_t uid) {
struct passwd pwent; struct passwd pwent;
// determine the max pwbuf size from sysconf, and hardcode // Determine the max pwbuf size from sysconf, and hardcode
// a default if this not available through sysconf. // a default if this not available through sysconf.
//
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1) if (bufsize == -1)
bufsize = 1024; bufsize = 1024;
@ -344,7 +608,8 @@ static char* get_user_name_slow(int vmid, TRAPS) {
strcat(usrdir_name, "/"); strcat(usrdir_name, "/");
strcat(usrdir_name, dentry->d_name); strcat(usrdir_name, dentry->d_name);
DIR* subdirp = os::opendir(usrdir_name); // Open the user directory.
DIR* subdirp = open_directory_secure(usrdir_name);
if (subdirp == NULL) { if (subdirp == NULL) {
FREE_C_HEAP_ARRAY(char, usrdir_name); FREE_C_HEAP_ARRAY(char, usrdir_name);
@ -464,28 +729,7 @@ static void remove_file(const char* path) {
} }
} }
// Cleanup stale shared memory resources
// remove file
//
// this method removes the file with the given file name in the
// named directory.
//
static void remove_file(const char* dirname, const char* filename) {
size_t nbytes = strlen(dirname) + strlen(filename) + 2;
char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
strcpy(path, dirname);
strcat(path, "/");
strcat(path, filename);
remove_file(path);
FREE_C_HEAP_ARRAY(char, path);
}
// cleanup stale shared memory resources
// //
// This method attempts to remove all stale shared memory files in // This method attempts to remove all stale shared memory files in
// the named user temporary directory. It scans the named directory // the named user temporary directory. It scans the named directory
@ -493,33 +737,26 @@ static void remove_file(const char* dirname, const char* filename) {
// process id is extracted from the file name and a test is run to // process id is extracted from the file name and a test is run to
// determine if the process is alive. If the process is not alive, // determine if the process is alive. If the process is not alive,
// any stale file resources are removed. // any stale file resources are removed.
//
static void cleanup_sharedmem_resources(const char* dirname) { static void cleanup_sharedmem_resources(const char* dirname) {
// open the user temp directory int saved_cwd_fd;
DIR* dirp = os::opendir(dirname); // Open the directory.
DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
if (dirp == NULL) { if (dirp == NULL) {
// directory doesn't exist, so there is nothing to cleanup // Directory doesn't exist or is insecure, so there is nothing to cleanup.
return; return;
} }
if (!is_directory_secure(dirname)) { // For each entry in the directory that matches the expected file
// the directory is not a secure directory
os::closedir(dirp);
return;
}
// for each entry in the directory that matches the expected file
// name pattern, determine if the file resources are stale and if // name pattern, determine if the file resources are stale and if
// so, remove the file resources. Note, instrumented HotSpot processes // so, remove the file resources. Note, instrumented HotSpot processes
// for this user may start and/or terminate during this search and // for this user may start and/or terminate during this search and
// remove or create new files in this directory. The behavior of this // remove or create new files in this directory. The behavior of this
// loop under these conditions is dependent upon the implementation of // loop under these conditions is dependent upon the implementation of
// opendir/readdir. // opendir/readdir.
//
struct dirent* entry; struct dirent* entry;
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
errno = 0; errno = 0;
while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
@ -529,56 +766,55 @@ static void cleanup_sharedmem_resources(const char* dirname) {
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
// attempt to remove all unexpected files, except "." and ".." // Attempt to remove all unexpected files, except "." and "..".
remove_file(dirname, entry->d_name); unlink(entry->d_name);
} }
errno = 0; errno = 0;
continue; continue;
} }
// we now have a file name that converts to a valid integer // We now have a file name that converts to a valid integer
// that could represent a process id . if this process id // that could represent a process id . if this process id
// matches the current process id or the process is not running, // matches the current process id or the process is not running,
// then remove the stale file resources. // then remove the stale file resources.
// //
// process liveness is detected by sending signal number 0 to // Process liveness is detected by sending signal number 0 to
// the process id (see kill(2)). if kill determines that the // the process id (see kill(2)). if kill determines that the
// process does not exist, then the file resources are removed. // process does not exist, then the file resources are removed.
// if kill determines that that we don't have permission to // if kill determines that that we don't have permission to
// signal the process, then the file resources are assumed to // signal the process, then the file resources are assumed to
// be stale and are removed because the resources for such a // be stale and are removed because the resources for such a
// process should be in a different user specific directory. // process should be in a different user specific directory.
//
if ((pid == os::current_process_id()) || if ((pid == os::current_process_id()) ||
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) { (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
remove_file(dirname, entry->d_name); unlink(entry->d_name);
} }
errno = 0; errno = 0;
} }
os::closedir(dirp);
FREE_C_HEAP_ARRAY(char, dbuf); // Close the directory and reset the current working directory.
close_directory_secure_cwd(dirp, saved_cwd_fd);
FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
} }
// make the user specific temporary directory. Returns true if // Make the user specific temporary directory. Returns true if
// the directory exists and is secure upon return. Returns false // the directory exists and is secure upon return. Returns false
// if the directory exists but is either a symlink, is otherwise // if the directory exists but is either a symlink, is otherwise
// insecure, or if an error occurred. // insecure, or if an error occurred.
//
static bool make_user_tmp_dir(const char* dirname) { static bool make_user_tmp_dir(const char* dirname) {
// create the directory with 0755 permissions. note that the directory // Create the directory with 0755 permissions. note that the directory
// will be owned by euid::egid, which may not be the same as uid::gid. // will be owned by euid::egid, which may not be the same as uid::gid.
//
if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) { if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
if (errno == EEXIST) { if (errno == EEXIST) {
// The directory already exists and was probably created by another // The directory already exists and was probably created by another
// JVM instance. However, this could also be the result of a // JVM instance. However, this could also be the result of a
// deliberate symlink. Verify that the existing directory is safe. // deliberate symlink. Verify that the existing directory is safe.
//
if (!is_directory_secure(dirname)) { if (!is_directory_secure(dirname)) {
// directory is not secure // Directory is not secure.
if (PrintMiscellaneous && Verbose) { if (PrintMiscellaneous && Verbose) {
warning("%s directory is insecure\n", dirname); warning("%s directory is insecure\n", dirname);
} }
@ -614,19 +850,63 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
return -1; return -1;
} }
int result; int saved_cwd_fd;
// Open the directory and set the current working directory to it.
RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result); DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
if (result == OS_ERR) { if (dirp == NULL) {
if (PrintMiscellaneous && Verbose) { // Directory doesn't exist or is insecure, so cannot create shared
warning("could not create file %s: %s\n", filename, strerror(errno)); // memory file.
}
return -1; return -1;
} }
// Open the filename in the current directory.
// Cannot use O_TRUNC here; truncation of an existing file has to happen
// after the is_file_secure() check below.
int result;
// No O_NOFOLLOW defined at buildtime, and it is not documented for open;
// so provide a workaround in this case.
#ifdef O_NOFOLLOW
RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
#else
// workaround function (jdk6 code)
RESTARTABLE(::open_o_nofollow(filename, O_RDWR|O_CREAT, S_IREAD|S_IWRITE), result);
#endif
if (result == OS_ERR) {
if (PrintMiscellaneous && Verbose) {
if (errno == ELOOP) {
warning("file %s is a symlink and is not secure\n", filename);
} else {
warning("could not create file %s: %s\n", filename, strerror(errno));
}
}
// Close the directory and reset the current working directory.
close_directory_secure_cwd(dirp, saved_cwd_fd);
return -1;
}
// Close the directory and reset the current working directory.
close_directory_secure_cwd(dirp, saved_cwd_fd);
// save the file descriptor // save the file descriptor
int fd = result; int fd = result;
// Check to see if the file is secure.
if (!is_file_secure(fd, filename)) {
::close(fd);
return -1;
}
// Truncate the file to get rid of any existing data.
RESTARTABLE(::ftruncate(fd, (off_t)0), result);
if (result == OS_ERR) {
if (PrintMiscellaneous && Verbose) {
warning("could not truncate shared memory file: %s\n", strerror(errno));
}
::close(fd);
return -1;
}
// set the file size // set the file size
RESTARTABLE(::ftruncate(fd, (off_t)size), result); RESTARTABLE(::ftruncate(fd, (off_t)size), result);
if (result == OS_ERR) { if (result == OS_ERR) {
@ -648,7 +928,14 @@ static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
// open the file // open the file
int result; int result;
// No O_NOFOLLOW defined at buildtime, and it is not documented for open;
// so provide a workaround in this case
#ifdef O_NOFOLLOW
RESTARTABLE(::open(filename, oflags), result); RESTARTABLE(::open(filename, oflags), result);
#else
RESTARTABLE(::open_o_nofollow(filename, oflags), result);
#endif
if (result == OS_ERR) { if (result == OS_ERR) {
if (errno == ENOENT) { if (errno == ENOENT) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
@ -662,8 +949,15 @@ static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno)); THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
} }
} }
int fd = result;
return result; // Check to see if the file is secure.
if (!is_file_secure(fd, filename)) {
::close(fd);
return -1;
}
return fd;
} }
// create a named shared memory region. returns the address of the // create a named shared memory region. returns the address of the
@ -695,13 +989,21 @@ static char* mmap_create_shared(size_t size) {
char* dirname = get_user_tmp_dir(user_name); char* dirname = get_user_tmp_dir(user_name);
char* filename = get_sharedmem_filename(dirname, vmid); char* filename = get_sharedmem_filename(dirname, vmid);
// Get the short filename.
char* short_filename = strrchr(filename, '/');
if (short_filename == NULL) {
short_filename = filename;
} else {
short_filename++;
}
// cleanup any stale shared memory files // cleanup any stale shared memory files
cleanup_sharedmem_resources(dirname); cleanup_sharedmem_resources(dirname);
assert(((size > 0) && (size % os::vm_page_size() == 0)), assert(((size > 0) && (size % os::vm_page_size() == 0)),
"unexpected PerfMemory region size"); "unexpected PerfMemory region size");
fd = create_sharedmem_resources(dirname, filename, size); fd = create_sharedmem_resources(dirname, short_filename, size);
FREE_C_HEAP_ARRAY(char, user_name); FREE_C_HEAP_ARRAY(char, user_name);
FREE_C_HEAP_ARRAY(char, dirname); FREE_C_HEAP_ARRAY(char, dirname);
@ -733,6 +1035,9 @@ static char* mmap_create_shared(size_t size) {
// clear the shared memory region // clear the shared memory region
(void)::memset((void*) mapAddress, 0, size); (void)::memset((void*) mapAddress, 0, size);
// It does not go through os api, the operation has to record from here.
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
return mapAddress; return mapAddress;
} }
@ -807,7 +1112,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
char* mapAddress; char* mapAddress;
int result; int result;
int fd; int fd;
size_t size; size_t size = 0;
const char* luser = NULL; const char* luser = NULL;
int mmap_prot; int mmap_prot;
@ -819,12 +1124,18 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
// constructs for the file and the shared memory mapping. // constructs for the file and the shared memory mapping.
if (mode == PerfMemory::PERF_MODE_RO) { if (mode == PerfMemory::PERF_MODE_RO) {
mmap_prot = PROT_READ; mmap_prot = PROT_READ;
// No O_NOFOLLOW defined at buildtime, and it is not documented for open.
#ifdef O_NOFOLLOW
file_flags = O_RDONLY | O_NOFOLLOW;
#else
file_flags = O_RDONLY; file_flags = O_RDONLY;
#endif
} }
else if (mode == PerfMemory::PERF_MODE_RW) { else if (mode == PerfMemory::PERF_MODE_RW) {
#ifdef LATER #ifdef LATER
mmap_prot = PROT_READ | PROT_WRITE; mmap_prot = PROT_READ | PROT_WRITE;
file_flags = O_RDWR; file_flags = O_RDWR | O_NOFOLLOW;
#else #else
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unsupported access mode"); "Unsupported access mode");
@ -853,9 +1164,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
// store file, we don't follow them when attaching either. // store file, we don't follow them when attaching either.
// //
if (!is_directory_secure(dirname)) { if (!is_directory_secure(dirname)) {
FREE_C_HEAP_ARRAY(char, dirname); FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
if (luser != user) { if (luser != user) {
FREE_C_HEAP_ARRAY(char, luser); FREE_C_HEAP_ARRAY(char, luser, mtInternal);
} }
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found"); "Process not found");
@ -901,6 +1212,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
"Could not map PerfMemory"); "Could not map PerfMemory");
} }
// It does not go through os api, the operation has to record from here.
MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC, mtInternal);
*addr = mapAddress; *addr = mapAddress;
*sizep = size; *sizep = size;

View file

@ -199,15 +199,10 @@ void CodeCache::initialize_heaps() {
} }
guarantee(NonProfiledCodeHeapSize + ProfiledCodeHeapSize + NonNMethodCodeHeapSize <= ReservedCodeCacheSize, "Size check"); guarantee(NonProfiledCodeHeapSize + ProfiledCodeHeapSize + NonNMethodCodeHeapSize <= ReservedCodeCacheSize, "Size check");
// Align reserved sizes of CodeHeaps // Align CodeHeaps
size_t non_method_size = ReservedCodeSpace::allocation_align_size_up(NonNMethodCodeHeapSize); size_t alignment = heap_alignment();
size_t profiled_size = ReservedCodeSpace::allocation_align_size_up(ProfiledCodeHeapSize); size_t non_method_size = align_size_up(NonNMethodCodeHeapSize, alignment);
size_t non_profiled_size = ReservedCodeSpace::allocation_align_size_up(NonProfiledCodeHeapSize); size_t profiled_size = align_size_down(ProfiledCodeHeapSize, alignment);
// Compute initial sizes of CodeHeaps
size_t init_non_method_size = MIN2(InitialCodeCacheSize, non_method_size);
size_t init_profiled_size = MIN2(InitialCodeCacheSize, profiled_size);
size_t init_non_profiled_size = MIN2(InitialCodeCacheSize, non_profiled_size);
// Reserve one continuous chunk of memory for CodeHeaps and split it into // Reserve one continuous chunk of memory for CodeHeaps and split it into
// parts for the individual heaps. The memory layout looks like this: // parts for the individual heaps. The memory layout looks like this:
@ -216,18 +211,27 @@ void CodeCache::initialize_heaps() {
// Profiled nmethods // Profiled nmethods
// Non-nmethods // Non-nmethods
// ---------- low ------------ // ---------- low ------------
ReservedCodeSpace rs = reserve_heap_memory(non_profiled_size + profiled_size + non_method_size); ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
ReservedSpace non_method_space = rs.first_part(non_method_size); ReservedSpace non_method_space = rs.first_part(non_method_size);
ReservedSpace rest = rs.last_part(non_method_size); ReservedSpace rest = rs.last_part(non_method_size);
ReservedSpace profiled_space = rest.first_part(profiled_size); ReservedSpace profiled_space = rest.first_part(profiled_size);
ReservedSpace non_profiled_space = rest.last_part(profiled_size); ReservedSpace non_profiled_space = rest.last_part(profiled_size);
// Non-nmethods (stubs, adapters, ...) // Non-nmethods (stubs, adapters, ...)
add_heap(non_method_space, "CodeHeap 'non-nmethods'", init_non_method_size, CodeBlobType::NonNMethod); add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod);
// Tier 2 and tier 3 (profiled) methods // Tier 2 and tier 3 (profiled) methods
add_heap(profiled_space, "CodeHeap 'profiled nmethods'", init_profiled_size, CodeBlobType::MethodProfiled); add_heap(profiled_space, "CodeHeap 'profiled nmethods'", CodeBlobType::MethodProfiled);
// Tier 1 and tier 4 (non-profiled) methods and native methods // Tier 1 and tier 4 (non-profiled) methods and native methods
add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", init_non_profiled_size, CodeBlobType::MethodNonProfiled); add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", CodeBlobType::MethodNonProfiled);
}
size_t CodeCache::heap_alignment() {
// If large page support is enabled, align code heaps according to large
// page size to make sure that code cache is covered by large pages.
const size_t page_size = os::can_execute_large_page_memory() ?
os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8) :
os::vm_page_size();
return MAX2(page_size, (size_t) os::vm_allocation_granularity());
} }
ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) { ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
@ -284,7 +288,7 @@ const char* CodeCache::get_code_heap_flag_name(int code_blob_type) {
return NULL; return NULL;
} }
void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type) { void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) {
// Check if heap is needed // Check if heap is needed
if (!heap_available(code_blob_type)) { if (!heap_available(code_blob_type)) {
return; return;
@ -295,8 +299,8 @@ void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial
_heaps->append(heap); _heaps->append(heap);
// Reserve Space // Reserve Space
size_t size_initial = MIN2(InitialCodeCacheSize, rs.size());
size_initial = round_to(size_initial, os::vm_page_size()); size_initial = round_to(size_initial, os::vm_page_size());
if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) { if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) {
vm_exit_during_initialization("Could not reserve enough space for code cache"); vm_exit_during_initialization("Could not reserve enough space for code cache");
} }
@ -840,7 +844,7 @@ void CodeCache::initialize() {
} else { } else {
// Use a single code heap // Use a single code heap
ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize); ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
add_heap(rs, "CodeCache", InitialCodeCacheSize, CodeBlobType::All); add_heap(rs, "CodeCache", CodeBlobType::All);
} }
// Initialize ICache flush mechanism // Initialize ICache flush mechanism

View file

@ -98,12 +98,13 @@ class CodeCache : AllStatic {
// CodeHeap management // CodeHeap management
static void initialize_heaps(); // Initializes the CodeHeaps static void initialize_heaps(); // Initializes the CodeHeaps
// Creates a new heap with the given name and size, containing CodeBlobs of the given type // Creates a new heap with the given name and size, containing CodeBlobs of the given type
static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type); static void add_heap(ReservedSpace rs, const char* name, int code_blob_type);
static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob
static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType
// Returns the name of the VM option to set the size of the corresponding CodeHeap // Returns the name of the VM option to set the size of the corresponding CodeHeap
static const char* get_code_heap_flag_name(int code_blob_type); static const char* get_code_heap_flag_name(int code_blob_type);
static bool heap_available(int code_blob_type); // Returns true if an own CodeHeap for the given CodeBlobType is available static bool heap_available(int code_blob_type); // Returns true if an own CodeHeap for the given CodeBlobType is available
static size_t heap_alignment(); // Returns the alignment of the CodeHeaps in bytes
static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps
// Iteration // Iteration

View file

@ -553,7 +553,8 @@ static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
int match = MethodMatcher::Exact; int match = MethodMatcher::Exact;
while (name[0] == '*') { while (name[0] == '*') {
match |= MethodMatcher::Suffix; match |= MethodMatcher::Suffix;
strcpy(name, name + 1); // Copy remaining string plus NUL to the beginning
memmove(name, name + 1, strlen(name + 1) + 1);
} }
if (strcmp(name, "*") == 0) return MethodMatcher::Any; if (strcmp(name, "*") == 0) return MethodMatcher::Any;
@ -689,6 +690,13 @@ static MethodMatcher* scan_flag_and_value(const char* type, const char* line, in
return NULL; return NULL;
} }
int skip_whitespace(char* line) {
// Skip any leading spaces
int whitespace_read = 0;
sscanf(line, "%*[ \t]%n", &whitespace_read);
return whitespace_read;
}
void CompilerOracle::parse_from_line(char* line) { void CompilerOracle::parse_from_line(char* line) {
if (line[0] == '\0') return; if (line[0] == '\0') return;
if (line[0] == '#') return; if (line[0] == '#') return;
@ -755,15 +763,9 @@ void CompilerOracle::parse_from_line(char* line) {
line += bytes_read; line += bytes_read;
// Skip any leading spaces before signature
int whitespace_read = 0;
sscanf(line, "%*[ \t]%n", &whitespace_read);
if (whitespace_read > 0) {
line += whitespace_read;
}
// there might be a signature following the method. // there might be a signature following the method.
// signatures always begin with ( so match that by hand // signatures always begin with ( so match that by hand
line += skip_whitespace(line);
if (1 == sscanf(line, "(%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { if (1 == sscanf(line, "(%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
sig[0] = '('; sig[0] = '(';
line += bytes_read; line += bytes_read;
@ -786,7 +788,9 @@ void CompilerOracle::parse_from_line(char* line) {
// //
// For future extensions: extend scan_flag_and_value() // For future extensions: extend scan_flag_and_value()
char option[256]; // stores flag for Type (1) and type of Type (2) char option[256]; // stores flag for Type (1) and type of Type (2)
while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
line += skip_whitespace(line);
while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
if (match != NULL && !_quiet) { if (match != NULL && !_quiet) {
// Print out the last match added // Print out the last match added
ttyLocker ttyl; ttyLocker ttyl;
@ -816,6 +820,7 @@ void CompilerOracle::parse_from_line(char* line) {
// Type (1) option // Type (1) option
match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true); match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true);
} }
line += skip_whitespace(line);
} // while( } // while(
} else { } else {
match = add_predicate(command, c_name, c_match, m_name, m_match, signature); match = add_predicate(command, c_name, c_match, m_name, m_match, signature);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1351,7 +1351,6 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar
Node* cache = __ ConI(cache_i); Node* cache = __ ConI(cache_i);
Node* md2 = __ ConI(md2_i); Node* md2 = __ ConI(md2_i);
Node* lastChar = __ ConI(target_array->char_at(target_length - 1)); Node* lastChar = __ ConI(target_array->char_at(target_length - 1));
Node* targetCount = __ ConI(target_length);
Node* targetCountLess1 = __ ConI(target_length - 1); Node* targetCountLess1 = __ ConI(target_length - 1);
Node* targetOffset = __ ConI(targetOffset_i); Node* targetOffset = __ ConI(targetOffset_i);
Node* sourceEnd = __ SubI(__ AddI(sourceOffset, sourceCount), targetCountLess1); Node* sourceEnd = __ SubI(__ AddI(sourceOffset, sourceCount), targetCountLess1);
@ -1408,8 +1407,6 @@ bool LibraryCallKit::inline_string_indexOf() {
Node* arg = argument(1); Node* arg = argument(1);
Node* result; Node* result;
// Disable the use of pcmpestri until it can be guaranteed that
// the load doesn't cross into the uncommited space.
if (Matcher::has_match_rule(Op_StrIndexOf) && if (Matcher::has_match_rule(Op_StrIndexOf) &&
UseSSE42Intrinsics) { UseSSE42Intrinsics) {
// Generate SSE4.2 version of indexOf // Generate SSE4.2 version of indexOf
@ -1421,9 +1418,6 @@ bool LibraryCallKit::inline_string_indexOf() {
return true; return true;
} }
ciInstanceKlass* str_klass = env()->String_klass();
const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass);
// Make the merge point // Make the merge point
RegionNode* result_rgn = new RegionNode(4); RegionNode* result_rgn = new RegionNode(4);
Node* result_phi = new PhiNode(result_rgn, TypeInt::INT); Node* result_phi = new PhiNode(result_rgn, TypeInt::INT);

View file

@ -2475,7 +2475,7 @@ void Scheduling::DoScheduling() {
if( iop == Op_Con ) continue; // Do not schedule Top if( iop == Op_Con ) continue; // Do not schedule Top
if( iop == Op_Node && // Do not schedule PhiNodes, ProjNodes if( iop == Op_Node && // Do not schedule PhiNodes, ProjNodes
mach->pipeline() == MachNode::pipeline_class() && mach->pipeline() == MachNode::pipeline_class() &&
!n->is_SpillCopy() ) // Breakpoints, Prolog, etc !n->is_SpillCopy() && !n->is_MachMerge() ) // Breakpoints, Prolog, etc
continue; continue;
break; // Funny loop structure to be sure... break; // Funny loop structure to be sure...
} }

View file

@ -428,6 +428,7 @@ int PhaseChaitin::possibly_merge_multidef(Node *n, uint k, Block *block, RegToDe
// Insert the merge node into the block before the first use. // Insert the merge node into the block before the first use.
uint use_index = block->find_node(reg2defuse.at(reg).first_use()); uint use_index = block->find_node(reg2defuse.at(reg).first_use());
block->insert_node(merge, use_index++); block->insert_node(merge, use_index++);
_cfg.map_node_to_block(merge, block);
// Let the allocator know about the new node, use the same lrg // Let the allocator know about the new node, use the same lrg
_lrg_map.extend(merge->_idx, lrg); _lrg_map.extend(merge->_idx, lrg);

View file

@ -1127,7 +1127,7 @@ static void no_shared_spaces(const char* message) {
#endif #endif
intx Arguments::scaled_compile_threshold(intx threshold, double scale) { intx Arguments::scaled_compile_threshold(intx threshold, double scale) {
if (scale == 1.0 || scale < 0.0) { if (scale == 1.0 || scale <= 0.0) {
return threshold; return threshold;
} else { } else {
return (intx)(threshold * scale); return (intx)(threshold * scale);
@ -1143,7 +1143,7 @@ intx Arguments::scaled_freq_log(intx freq_log, double scale) {
// Check value to avoid calculating log2 of 0. // Check value to avoid calculating log2 of 0.
if (scale == 0.0) { if (scale == 0.0) {
return 1; return freq_log;
} }
intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale); intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale);
@ -3479,8 +3479,10 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
set_mode_flags(_int); set_mode_flags(_int);
} }
if ((TieredCompilation && CompileThresholdScaling == 0) // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
|| (!TieredCompilation && scaled_compile_threshold(CompileThreshold) == 0)) { // but like -Xint, leave compilation thresholds unaffected.
// With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
set_mode_flags(_int); set_mode_flags(_int);
} }

View file

@ -84,6 +84,13 @@ public class CheckCompileThresholdScaling {
"-XX:CompileThresholdScaling=0.75", "-XX:CompileThresholdScaling=0.75",
"-version" "-version"
}, },
{
"-XX:-TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CompileThreshold=1000",
"-XX:CompileThresholdScaling=0.0",
"-version"
},
{ {
"-XX:-TieredCompilation", "-XX:-TieredCompilation",
"-XX:+PrintFlagsFinal", "-XX:+PrintFlagsFinal",
@ -107,6 +114,11 @@ public class CheckCompileThresholdScaling {
"intx CompileThreshold := 750 {pd product}", "intx CompileThreshold := 750 {pd product}",
"double CompileThresholdScaling := 0.750000 {product}" "double CompileThresholdScaling := 0.750000 {product}"
}, },
{
"intx CompileThreshold := 1000 {pd product}",
"double CompileThresholdScaling := 0.000000 {product}",
"interpreted mode"
},
{ {
"intx CompileThreshold := 0 {pd product}", "intx CompileThreshold := 0 {pd product}",
"double CompileThresholdScaling := 0.750000 {product}", "double CompileThresholdScaling := 0.750000 {product}",
@ -295,21 +307,21 @@ public class CheckCompileThresholdScaling {
"double CompileThresholdScaling := 2.000000 {product}" "double CompileThresholdScaling := 2.000000 {product}"
}, },
{ {
"intx Tier0BackedgeNotifyFreqLog := 0 {product}", "intx Tier0BackedgeNotifyFreqLog := 10 {product}",
"intx Tier0InvokeNotifyFreqLog := 0 {product}", "intx Tier0InvokeNotifyFreqLog := 7 {product}",
"intx Tier23InlineeNotifyFreqLog := 0 {product}", "intx Tier23InlineeNotifyFreqLog := 20 {product}",
"intx Tier2BackedgeNotifyFreqLog := 0 {product}", "intx Tier2BackedgeNotifyFreqLog := 14 {product}",
"intx Tier2InvokeNotifyFreqLog := 0 {product}", "intx Tier2InvokeNotifyFreqLog := 11 {product}",
"intx Tier3BackEdgeThreshold := 0 {product}", "intx Tier3BackEdgeThreshold := 60000 {product}",
"intx Tier3BackedgeNotifyFreqLog := 0 {product}", "intx Tier3BackedgeNotifyFreqLog := 13 {product}",
"intx Tier3CompileThreshold := 0 {product}", "intx Tier3CompileThreshold := 2000 {product}",
"intx Tier3InvocationThreshold := 0 {product}", "intx Tier3InvocationThreshold := 200 {product}",
"intx Tier3InvokeNotifyFreqLog := 0 {product}", "intx Tier3InvokeNotifyFreqLog := 10 {product}",
"intx Tier3MinInvocationThreshold := 0 {product}", "intx Tier3MinInvocationThreshold := 100 {product}",
"intx Tier4BackEdgeThreshold := 0 {product}", "intx Tier4BackEdgeThreshold := 40000 {product}",
"intx Tier4CompileThreshold := 0 {product}", "intx Tier4CompileThreshold := 15000 {product}",
"intx Tier4InvocationThreshold := 0 {product}", "intx Tier4InvocationThreshold := 5000 {product}",
"intx Tier4MinInvocationThreshold := 0 {product}", "intx Tier4MinInvocationThreshold := 600 {product}",
"double CompileThresholdScaling := 0.000000 {product}", "double CompileThresholdScaling := 0.000000 {product}",
"interpreted mode" "interpreted mode"
} }

View file

@ -82,6 +82,9 @@ public class PrintCodeCacheRunner implements CodeCacheCLITestCase.Runner {
ExitCode.OK, ExitCode.OK,
testCaseDescription.getTestOptions(options, testCaseDescription.getTestOptions(options,
CommandLineOptionTest.prepareBooleanFlag( CommandLineOptionTest.prepareBooleanFlag(
"PrintCodeCache", printCodeCache))); "PrintCodeCache", printCodeCache),
// Do not use large pages to avoid large page
// alignment of code heaps affecting their size.
"-XX:-UseLargePages"));
} }
} }

View file

@ -36,7 +36,7 @@ public class CodeCacheStressRunner {
try { try {
// adjust timeout and substract vm init and exit time // adjust timeout and substract vm init and exit time
long timeout = Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT); long timeout = Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT);
timeout *= 0.9; timeout *= 0.8;
new TimeLimitedRunner(timeout, 2.0d, this::test).call(); new TimeLimitedRunner(timeout, 2.0d, this::test).call();
} catch (Exception e) { } catch (Exception e) {
throw new Error("Exception occurred during test execution", e); throw new Error("Exception occurred during test execution", e);

View file

@ -77,7 +77,7 @@ public class OverloadCompileQueueTest implements Runnable {
} }
public OverloadCompileQueueTest() { public OverloadCompileQueueTest() {
Helper.startInfiniteLoopThread(this::lockUnlock); Helper.startInfiniteLoopThread(this::lockUnlock, 100L);
} }
@Override @Override
@ -99,8 +99,9 @@ public class OverloadCompileQueueTest implements Runnable {
private void lockUnlock() { private void lockUnlock() {
try { try {
int sleep = Helper.RNG.nextInt(MAX_SLEEP);
Helper.WHITE_BOX.lockCompilation(); Helper.WHITE_BOX.lockCompilation();
Thread.sleep(Helper.RNG.nextInt(MAX_SLEEP)); Thread.sleep(sleep);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new Error("TESTBUG: lockUnlocker thread was unexpectedly interrupted", e); throw new Error("TESTBUG: lockUnlocker thread was unexpectedly interrupted", e);
} finally { } finally {

View file

@ -21,12 +21,15 @@
* questions. * questions.
*/ */
import java.io.PrintWriter;
import java.io.File;
import com.oracle.java.testlibrary.*; import com.oracle.java.testlibrary.*;
/* /*
* @test CheckCompileCommandOption * @test CheckCompileCommandOption
* @bug 8055286 8056964 8059847 * @bug 8055286 8056964 8059847 8069035
* @summary "Checks parsing of -XX:+CompileCommand=option" * @summary "Checks parsing of -XX:CompileCommand=option"
* @library /testlibrary * @library /testlibrary
* @run main CheckCompileCommandOption * @run main CheckCompileCommandOption
*/ */
@ -45,38 +48,69 @@ public class CheckCompileCommandOption {
// have the the following types: intx, uintx, bool, ccstr, // have the the following types: intx, uintx, bool, ccstr,
// ccstrlist, and double. // ccstrlist, and double.
private static final String[][] FILE_ARGUMENTS = {
{
"-XX:CompileCommandFile=" + new File(System.getProperty("test.src", "."), "command1.txt"),
"-version"
},
{
"-XX:CompileCommandFile=" + new File(System.getProperty("test.src", "."), "command2.txt"),
"-version"
}
};
private static final String[][] FILE_EXPECTED_OUTPUT = {
{
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption4 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption9 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption10 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption11 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption12 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption13 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption14 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption15 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption16 = true"
},
{
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
"CompileCommand: option Test.test bool MyBoolOption = false",
"CompileCommand: option Test.test intx MyIntxOption = -1",
"CompileCommand: option Test.test uintx MyUintxOption = 1",
"CompileCommand: option Test.test bool MyFlag = true",
"CompileCommand: option Test.test double MyDoubleOption = 1.123000"
}
};
private static final String[][] TYPE_1_ARGUMENTS = { private static final String[][] TYPE_1_ARGUMENTS = {
{ {
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1", "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1",
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2", "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2",
"-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3", "-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3",
"-XX:CompileCommand=option,com/oracle/Test::test,MyBoolOption4", "-XX:CompileCommand=option,com/oracle/Test::test,MyBoolOption4",
"-version" "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6",
}, "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8",
{
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1,MyBoolOption2",
"-version"
},
{
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption1,MyBoolOption2",
"-version" "-version"
} }
}; };
private static final String[][] TYPE_1_EXPECTED_OUTPUTS = { private static final String[][] TYPE_1_EXPECTED_OUTPUTS = {
{ {
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true", "CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true", "CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption3 = true", "CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption4 = true" "CompileCommand: option com/oracle/Test.test bool MyBoolOption4 = true",
}, "CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
{ "CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true", "CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true", "CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true"
},
{
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true",
"CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true",
} }
}; };
@ -88,38 +122,28 @@ public class CheckCompileCommandOption {
"-XX:CompileCommand=option,Test::test,intx,MyIntxOption,-1", "-XX:CompileCommand=option,Test::test,intx,MyIntxOption,-1",
"-XX:CompileCommand=option,Test::test,uintx,MyUintxOption,1", "-XX:CompileCommand=option,Test::test,uintx,MyUintxOption,1",
"-XX:CompileCommand=option,Test::test,MyFlag", "-XX:CompileCommand=option,Test::test,MyFlag",
"-XX:CompileCommand=option,Test::test,double,MyDoubleOption,1.123", "-XX:CompileCommand=option,Test::test,double,MyDoubleOption1,1.123",
"-version" "-XX:CompileCommand=option,Test.test,double,MyDoubleOption2,1.123",
}, "-XX:CompileCommand=option,Test::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123",
{
"-XX:CompileCommand=option,Test.test,double,MyDoubleOption,1.123",
"-version"
},
{
"-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntxOption,-1,uintx,MyUintxOption,1,MyFlag,double,MyDoubleOption,1.123",
"-version" "-version"
} }
}; };
private static final String[][] TYPE_2_EXPECTED_OUTPUTS = { private static final String[][] TYPE_2_EXPECTED_OUTPUTS = {
{ {
"CompilerOracle: option Test.test const char* MyListOption = '_foo _bar'", "CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
"CompilerOracle: option Test.test const char* MyStrOption = '_foo'", "CompileCommand: option Test.test const char* MyStrOption = '_foo'",
"CompilerOracle: option Test.test bool MyBoolOption = false", "CompileCommand: option Test.test bool MyBoolOption = false",
"CompilerOracle: option Test.test intx MyIntxOption = -1", "CompileCommand: option Test.test intx MyIntxOption = -1",
"CompilerOracle: option Test.test uintx MyUintxOption = 1", "CompileCommand: option Test.test uintx MyUintxOption = 1",
"CompilerOracle: option Test.test bool MyFlag = true", "CompileCommand: option Test.test bool MyFlag = true",
"CompilerOracle: option Test.test double MyDoubleOption = 1.123000" "CompileCommand: option Test.test double MyDoubleOption1 = 1.123000",
}, "CompileCommand: option Test.test double MyDoubleOption2 = 1.123000",
{ "CompileCommand: option Test.test bool MyBoolOptionX = false",
"CompilerOracle: option Test.test double MyDoubleOption = 1.123000" "CompileCommand: option Test.test intx MyIntxOptionX = -1",
}, "CompileCommand: option Test.test uintx MyUintxOptionX = 1",
{ "CompileCommand: option Test.test bool MyFlagX = true",
"CompilerOracle: option Test.test bool MyBoolOption = false", "CompileCommand: option Test.test double MyDoubleOptionX = 1.123000",
"CompilerOracle: option Test.test intx MyIntxOption = -1",
"CompilerOracle: option Test.test uintx MyUintxOption = 1",
"CompilerOracle: option Test.test bool MyFlag = true",
"CompilerOracle: option Test.test double MyDoubleOption = 1.123000",
} }
}; };
@ -172,7 +196,7 @@ public class CheckCompileCommandOption {
out.shouldContain(expected_output); out.shouldContain(expected_output);
} }
out.shouldNotContain("CompileCommand: unrecognized line"); out.shouldNotContain("CompileCommand: An error occured during parsing");
out.shouldHaveExitValue(0); out.shouldHaveExitValue(0);
} }
@ -183,7 +207,7 @@ public class CheckCompileCommandOption {
pb = ProcessTools.createJavaProcessBuilder(arguments); pb = ProcessTools.createJavaProcessBuilder(arguments);
out = new OutputAnalyzer(pb.start()); out = new OutputAnalyzer(pb.start());
out.shouldContain("CompileCommand: unrecognized line"); out.shouldContain("CompileCommand: An error occured during parsing");
out.shouldHaveExitValue(0); out.shouldHaveExitValue(0);
} }
@ -212,5 +236,10 @@ public class CheckCompileCommandOption {
for (String[] arguments: TYPE_2_INVALID_ARGUMENTS) { for (String[] arguments: TYPE_2_INVALID_ARGUMENTS) {
verifyInvalidOption(arguments); verifyInvalidOption(arguments);
} }
// Check if commands in command file are parsed correctly
for (int i = 0; i < FILE_ARGUMENTS.length; i++) {
verifyValidOption(FILE_ARGUMENTS[i], FILE_EXPECTED_OUTPUT[i]);
}
} }
} }

View file

@ -0,0 +1,78 @@
/*
* 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.
*
* 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.PrintWriter;
import java.io.File;
import com.oracle.java.testlibrary.*;
/*
* @test TestCompileCommand
* @bug 8069389
* @summary "Regression tests of -XX:CompileCommand"
* @library /testlibrary
* @run main TestCompileCommand
*/
public class TestCompileCommand {
private static final String[][] ARGUMENTS = {
{
"-XX:CompileCommand=print,*01234567890123456789012345678901234567890123456789,*0123456789012345678901234567890123456789",
"-version"
}
};
private static final String[][] OUTPUTS = {
{
"print *01234567890123456789012345678901234567890123456789.*0123456789012345678901234567890123456789"
}
};
private static void verifyValidOption(String[] arguments, String[] expected_outputs) throws Exception {
ProcessBuilder pb;
OutputAnalyzer out;
pb = ProcessTools.createJavaProcessBuilder(arguments);
out = new OutputAnalyzer(pb.start());
for (String expected_output : expected_outputs) {
out.shouldContain(expected_output);
}
out.shouldNotContain("CompileCommand: An error occured during parsing");
out.shouldHaveExitValue(0);
}
public static void main(String[] args) throws Exception {
if (ARGUMENTS.length != OUTPUTS.length) {
throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (1) options does not match.");
}
// Check if type (1) options are parsed correctly
for (int i = 0; i < ARGUMENTS.length; i++) {
verifyValidOption(ARGUMENTS[i], OUTPUTS[i]);
}
}
}

View file

@ -0,0 +1,12 @@
option,com/oracle/Test.test,MyBoolOption1
option,com/oracle/Test,test,MyBoolOption2
option,com.oracle.Test::test,MyBoolOption3
option,com/oracle/Test::test,MyBoolOption4
option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6
option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8
option,com/oracle/Test.test(I),MyBoolOption9
option,com/oracle/Test,test,(I),MyBoolOption10
option,com.oracle.Test::test(I),MyBoolOption11
option,com/oracle/Test::test(I),MyBoolOption12
option,com/oracle/Test.test(I),MyBoolOption13,MyBoolOption14
option,com/oracle/Test,test(I),MyBoolOption15,MyBoolOption16

View file

@ -0,0 +1,7 @@
option,Test::test,ccstrlist,MyListOption,_foo,_bar
option,Test::test,ccstr,MyStrOption,_foo
option,Test::test,bool,MyBoolOption,false
option,Test::test,intx,MyIntxOption,-1
option,Test::test,uintx,MyUintxOption,1
option,Test::test,MyFlag
option,Test::test,double,MyDoubleOption,1.123

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -119,13 +119,13 @@ public class TestRTMTotalCountIncrRate extends CommandLineOptionTest {
return new String[] { getMethodWithLockName() }; return new String[] { getMethodWithLockName() };
} }
public void lock(booleab forceAbort) { public void lock(boolean forceAbort) {
synchronized(monitor) { synchronized(monitor) {
if (forceAbort) { if (forceAbort) {
// We're calling native method in order to force // We're calling native method in order to force
// abort. It's done by explicit xabort call emitted // abort. It's done by explicit xabort call emitted
// in SharedRuntime::generate_native_wrapper. // in SharedRuntime::generate_native_wrapper.
// If an actuall JNI call will be replaced by // If an actual JNI call will be replaced by
// intrinsic - we'll be in trouble, since xabort // intrinsic - we'll be in trouble, since xabort
// will be no longer called and test may fail. // will be no longer called and test may fail.
UNSAFE.addressSize(); UNSAFE.addressSize();

View file

@ -34,7 +34,6 @@ import com.oracle.java.testlibrary.InfiniteLoop;
/* /*
* @test * @test
* @bug 8059624 8064669 * @bug 8059624 8064669
* @ignore 8066998
* @library /testlibrary /../../test/lib * @library /testlibrary /../../test/lib
* @build ForceNMethodSweepTest * @build ForceNMethodSweepTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
@ -42,7 +41,7 @@ import com.oracle.java.testlibrary.InfiniteLoop;
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:-TieredCompilation -XX:+WhiteBoxAPI * -XX:-TieredCompilation -XX:+WhiteBoxAPI
* -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::*
* ForceNMethodSweepTest * -XX:-BackgroundCompilation ForceNMethodSweepTest
* @summary testing of WB::forceNMethodSweep * @summary testing of WB::forceNMethodSweep
*/ */
public class ForceNMethodSweepTest extends CompilerWhiteBoxTest { public class ForceNMethodSweepTest extends CompilerWhiteBoxTest {

View file

@ -290,3 +290,4 @@ a12d347f84176200593999f4da91ae2bb86865b2 jdk9-b39
0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45 0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45
74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46 74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46
e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47 e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47
833051855168a973780fafeb6fc59e7370bcf400 jdk9-b48

View file

@ -270,8 +270,8 @@ public final class BasisLibrary {
if (Double.isNaN(start)) if (Double.isNaN(start))
return(EMPTYSTRING); return(EMPTYSTRING);
final int strlen = value.length(); final int strlen = value.length();
int istart = (int)Math.round(start) - 1; int istart = (int)Math.round(start) - 1;
if (istart > strlen) if (istart > strlen)
return(EMPTYSTRING); return(EMPTYSTRING);
@ -292,10 +292,11 @@ public final class BasisLibrary {
public static String substringF(String value, double start, double length) { public static String substringF(String value, double start, double length) {
if (Double.isInfinite(start) || if (Double.isInfinite(start) ||
Double.isNaN(start) || Double.isNaN(start) ||
Double.isNaN(length)) Double.isNaN(length) ||
length < 0)
return(EMPTYSTRING); return(EMPTYSTRING);
int istart = (int)Math.round(start) - 1; int istart = (int)Math.round(start) - 1;
final int isum; final int isum;
if (Double.isInfinite(length)) if (Double.isInfinite(length))
isum = Integer.MAX_VALUE; isum = Integer.MAX_VALUE;

View file

@ -1,15 +1,15 @@
/* /*
* reserved comment block * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 1999-2004 The Apache Software Foundation. * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * http://www.apache.org/licenses/LICENSE-2.0
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -17,36 +17,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
// $Id: XPathExpressionImpl.java,v 1.3 2005/09/27 09:40:43 sunithareddy Exp $
package com.sun.org.apache.xpath.internal.jaxp; package com.sun.org.apache.xpath.internal.jaxp;
import com.sun.org.apache.xpath.internal.*;
import javax.xml.transform.TransformerException;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager; import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import com.sun.org.apache.xpath.internal.objects.XObject;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.xpath.XPathExpressionException; import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathVariableResolver; import javax.xml.xpath.XPathVariableResolver;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.Node;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation; import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
/** /**
@ -54,22 +39,10 @@ import org.xml.sax.InputSource;
* *
* @author Ramesh Mandava * @author Ramesh Mandava
*/ */
public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{ public class XPathExpressionImpl extends XPathImplUtil implements XPathExpression {
private XPathFunctionResolver functionResolver;
private XPathVariableResolver variableResolver;
private JAXPPrefixResolver prefixResolver;
private com.sun.org.apache.xpath.internal.XPath xpath; private com.sun.org.apache.xpath.internal.XPath xpath;
// By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
private boolean featureSecureProcessing = false;
private boolean useServicesMechanism = true;
private final FeatureManager featureManager;
/** Protected constructor to prevent direct instantiation; use compile() /** Protected constructor to prevent direct instantiation; use compile()
* from the context. * from the context.
*/ */
@ -81,7 +54,7 @@ public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{
protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath, protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
JAXPPrefixResolver prefixResolver, JAXPPrefixResolver prefixResolver,
XPathFunctionResolver functionResolver, XPathFunctionResolver functionResolver,
XPathVariableResolver variableResolver ) { XPathVariableResolver variableResolver) {
this(xpath, prefixResolver, functionResolver, variableResolver, this(xpath, prefixResolver, functionResolver, variableResolver,
false, true, new FeatureManager()); false, true, new FeatureManager());
}; };
@ -89,291 +62,108 @@ public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{
protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath, protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver, JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
XPathVariableResolver variableResolver, boolean featureSecureProcessing, XPathVariableResolver variableResolver, boolean featureSecureProcessing,
boolean useServicesMechanism, FeatureManager featureManager ) { boolean useServiceMechanism, FeatureManager featureManager) {
this.xpath = xpath; this.xpath = xpath;
this.prefixResolver = prefixResolver; this.prefixResolver = prefixResolver;
this.functionResolver = functionResolver; this.functionResolver = functionResolver;
this.variableResolver = variableResolver; this.variableResolver = variableResolver;
this.featureSecureProcessing = featureSecureProcessing; this.featureSecureProcessing = featureSecureProcessing;
this.useServicesMechanism = useServicesMechanism; this.useServiceMechanism = useServiceMechanism;
this.featureManager = featureManager; this.featureManager = featureManager;
}; };
public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath ) { public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath) {
this.xpath = xpath; this.xpath = xpath;
} }
public Object eval(Object item, QName returnType) public Object eval(Object item, QName returnType)
throws javax.xml.transform.TransformerException { throws javax.xml.transform.TransformerException {
XObject resultObject = eval ( item ); XObject resultObject = eval(item, xpath);
return getResultAsType( resultObject, returnType ); return getResultAsType(resultObject, returnType);
} }
private XObject eval ( Object contextItem ) @Override
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
if ( functionResolver != null ) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager );
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
} else {
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
}
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
XObject xobj = null;
Node contextNode = (Node)contextItem;
// We always need to have a ContextNode with Xalan XPath implementation
// To allow simple expression evaluation like 1+1 we are setting
// dummy Document as Context Node
if ( contextNode == null )
xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
else
xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
return xobj;
}
/**
* <p>Evaluate the compiled XPath expression in the specified context and
* return the result as the specified type.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined
* in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>returnType</code> is <code>null</code>, then a
* <code>NullPointerException</code> is thrown.</p>
*
* @param item The starting context (node or node list, for example).
* @param returnType The desired return type.
*
* @return The <code>Object</code> that is the result of evaluating the
* expression and converting the result to
* <code>returnType</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one
* of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>returnType</code> is
* <code>null</code>.
*/
public Object evaluate(Object item, QName returnType) public Object evaluate(Object item, QName returnType)
throws XPathExpressionException { throws XPathExpressionException {
//Validating parameters to enforce constraints defined by JAXP spec isSupported(returnType);
if ( returnType == null ) {
//Throwing NullPointerException as defined in spec
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"returnType"} );
throw new NullPointerException( fmsg );
}
// Checking if requested returnType is supported. returnType need to be
// defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
return eval( item, returnType); return eval(item, returnType);
} catch ( java.lang.NullPointerException npe ) { } catch (java.lang.NullPointerException npe) {
// If VariableResolver returns null Or if we get // If VariableResolver returns null Or if we get
// NullPointerException at this stage for some other reason // NullPointerException at this stage for some other reason
// then we have to reurn XPathException // then we have to reurn XPathException
throw new XPathExpressionException ( npe ); throw new XPathExpressionException (npe);
} catch ( javax.xml.transform.TransformerException te ) { } catch (javax.xml.transform.TransformerException te) {
Throwable nestedException = te.getException(); Throwable nestedException = te.getException();
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
throw (javax.xml.xpath.XPathFunctionException)nestedException; throw (javax.xml.xpath.XPathFunctionException)nestedException;
} else { } else {
// For any other exceptions we need to throw // For any other exceptions we need to throw
// XPathExpressionException ( as per spec ) // XPathExpressionException (as per spec)
throw new XPathExpressionException( te); throw new XPathExpressionException(te);
} }
} }
} }
/**
* <p>Evaluate the compiled XPath expression in the specified context and @Override
* return the result as a <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(Object item, QName returnType)}
* with a <code>returnType</code> of
* {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
*
* @param item The starting context (node or node list, for example).
*
* @return The <code>String</code> that is the result of evaluating the
* expression and converting the result to a
* <code>String</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
*/
public String evaluate(Object item) public String evaluate(Object item)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( item, XPathConstants.STRING ); return (String)this.evaluate(item, XPathConstants.STRING);
} }
@Override
static DocumentBuilderFactory dbf = null;
static DocumentBuilder db = null;
static Document d = null;
/**
* <p>Evaluate the compiled XPath expression in the context of the
* specified <code>InputSource</code> and return the result as the
* specified type.</p>
*
* <p>This method builds a data model for the {@link InputSource} and calls
* {@link #evaluate(Object item, QName returnType)} on the resulting
* document object.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined in
* {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
*<p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
*
* @param source The <code>InputSource</code> of the document to evaluate
* over.
* @param returnType The desired return type.
*
* @return The <code>Object</code> that is the result of evaluating the
* expression and converting the result to
* <code>returnType</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one
* of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>source</code> or
* <code>returnType</code> is <code>null</code>.
*/
public Object evaluate(InputSource source, QName returnType) public Object evaluate(InputSource source, QName returnType)
throws XPathExpressionException { throws XPathExpressionException {
if ( ( source == null ) || ( returnType == null ) ) { isSupported (returnType);
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
null );
throw new NullPointerException ( fmsg );
}
// Checking if requested returnType is supported. returnType need to be
// defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
if ( dbf == null ) { Document document = getDocument(source);
dbf = FactoryImpl.getDOMFactory(useServicesMechanism); return eval(document, returnType);
dbf.setNamespaceAware( true ); } catch (TransformerException e) {
dbf.setValidating( false ); throw new XPathExpressionException(e);
}
db = dbf.newDocumentBuilder();
Document document = db.parse( source );
return eval( document, returnType );
} catch ( Exception e ) {
throw new XPathExpressionException ( e );
} }
} }
/** @Override
* <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
* <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
* {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
*
* @param source The <code>InputSource</code> of the document to evaluate over.
*
* @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
* <code>String</code>.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws NullPointerException If <code>source</code> is <code>null</code>.
*/
public String evaluate(InputSource source) public String evaluate(InputSource source)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( source, XPathConstants.STRING ); return (String)this.evaluate(source, XPathConstants.STRING);
} }
private boolean isSupported( QName returnType ) { @Override
// XPathConstants.STRING public <T>T evaluateExpression(Object item, Class<T> type)
if ( ( returnType.equals( XPathConstants.STRING ) ) || throws XPathExpressionException {
( returnType.equals( XPathConstants.NUMBER ) ) || isSupportedClassType(type);
( returnType.equals( XPathConstants.BOOLEAN ) ) ||
( returnType.equals( XPathConstants.NODE ) ) ||
( returnType.equals( XPathConstants.NODESET ) ) ) {
return true; try {
} XObject resultObject = eval(item, xpath);
return false; if (type.isAssignableFrom(XPathEvaluationResult.class)) {
} return getXPathResult(resultObject, type);
} else {
return XPathResultImpl.getValue(resultObject, type);
}
private Object getResultAsType( XObject resultObject, QName returnType ) } catch (javax.xml.transform.TransformerException te) {
throws javax.xml.transform.TransformerException { throw new XPathExpressionException(te);
// XPathConstants.STRING
if ( returnType.equals( XPathConstants.STRING ) ) {
return resultObject.str();
} }
// XPathConstants.NUMBER
if ( returnType.equals( XPathConstants.NUMBER ) ) {
return new Double ( resultObject.num());
}
// XPathConstants.BOOLEAN
if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
return new Boolean( resultObject.bool());
}
// XPathConstants.NODESET ---ORdered, UNOrdered???
if ( returnType.equals( XPathConstants.NODESET ) ) {
return resultObject.nodelist();
}
// XPathConstants.NODE
if ( returnType.equals( XPathConstants.NODE ) ) {
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return ni.nextNode();
}
// If isSupported check is already done then the execution path
// shouldn't come here. Being defensive
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString()});
throw new IllegalArgumentException ( fmsg );
} }
@Override
public XPathEvaluationResult<?> evaluateExpression(Object item)
throws XPathExpressionException {
return evaluateExpression(item, XPathEvaluationResult.class);
}
@Override
public <T>T evaluateExpression(InputSource source, Class<T> type)
throws XPathExpressionException {
Document document = getDocument(source);
return evaluateExpression(document, type);
}
@Override
public XPathEvaluationResult<?> evaluateExpression(InputSource source)
throws XPathExpressionException {
return evaluateExpression(source, XPathEvaluationResult.class);
}
} }

View file

@ -1,6 +1,5 @@
/* /*
* reserved comment block * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 1999-2004 The Apache Software Foundation. * Copyright 1999-2004 The Apache Software Foundation.
@ -28,55 +27,37 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathVariableResolver; import javax.xml.xpath.XPathVariableResolver;
import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpression;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xpath.internal.*; import com.sun.org.apache.xpath.internal.*;
import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager; import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import org.w3c.dom.Node;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.parsers.*;
import java.io.IOException;
/** /**
* The XPathImpl class provides implementation for the methods defined in * The XPathImpl class provides implementation for the methods defined in
* javax.xml.xpath.XPath interface. This provide simple access to the results * javax.xml.xpath.XPath interface. This provides simple access to the results
* of an XPath expression. * of an XPath expression.
* *
*
* @author Ramesh Mandava * @author Ramesh Mandava
*
* Updated 12/04/2014:
* New methods: evaluateExpression
* Refactored to share code with XPathExpressionImpl.
*/ */
public class XPathImpl implements javax.xml.xpath.XPath { public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
// Private variables // Private variables
private XPathVariableResolver variableResolver;
private XPathFunctionResolver functionResolver;
private XPathVariableResolver origVariableResolver; private XPathVariableResolver origVariableResolver;
private XPathFunctionResolver origFunctionResolver; private XPathFunctionResolver origFunctionResolver;
private NamespaceContext namespaceContext=null; private NamespaceContext namespaceContext=null;
private JAXPPrefixResolver prefixResolver;
// By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
private boolean featureSecureProcessing = false;
private boolean useServiceMechanism = true;
private final FeatureManager featureManager;
XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) { XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
this(vr, fr, false, true, new FeatureManager()); this(vr, fr, false, true, new FeatureManager());
} }
XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
boolean featureSecureProcessing, boolean useServiceMechanism, boolean featureSecureProcessing, boolean useServiceMechanism,
FeatureManager featureManager) { FeatureManager featureManager) {
this.origVariableResolver = this.variableResolver = vr; this.origVariableResolver = this.variableResolver = vr;
@ -86,451 +67,173 @@ public class XPathImpl implements javax.xml.xpath.XPath {
this.featureManager = featureManager; this.featureManager = featureManager;
} }
/**
* <p>Establishes a variable resolver.</p> //-Override-
*
* @param resolver Variable Resolver
*/
public void setXPathVariableResolver(XPathVariableResolver resolver) { public void setXPathVariableResolver(XPathVariableResolver resolver) {
if ( resolver == null ) { requireNonNull(resolver, "XPathVariableResolver");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPathVariableResolver"} );
throw new NullPointerException( fmsg );
}
this.variableResolver = resolver; this.variableResolver = resolver;
} }
/** //-Override-
* <p>Returns the current variable resolver.</p>
*
* @return Current variable resolver
*/
public XPathVariableResolver getXPathVariableResolver() { public XPathVariableResolver getXPathVariableResolver() {
return variableResolver; return variableResolver;
} }
/** //-Override-
* <p>Establishes a function resolver.</p>
*
* @param resolver XPath function resolver
*/
public void setXPathFunctionResolver(XPathFunctionResolver resolver) { public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
if ( resolver == null ) { requireNonNull(resolver, "XPathFunctionResolver");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPathFunctionResolver"} );
throw new NullPointerException( fmsg );
}
this.functionResolver = resolver; this.functionResolver = resolver;
} }
/** //-Override-
* <p>Returns the current function resolver.</p>
*
* @return Current function resolver
*/
public XPathFunctionResolver getXPathFunctionResolver() { public XPathFunctionResolver getXPathFunctionResolver() {
return functionResolver; return functionResolver;
} }
/** //-Override-
* <p>Establishes a namespace context.</p>
*
* @param nsContext Namespace context to use
*/
public void setNamespaceContext(NamespaceContext nsContext) { public void setNamespaceContext(NamespaceContext nsContext) {
if ( nsContext == null ) { requireNonNull(nsContext, "NamespaceContext");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"NamespaceContext"} );
throw new NullPointerException( fmsg );
}
this.namespaceContext = nsContext; this.namespaceContext = nsContext;
this.prefixResolver = new JAXPPrefixResolver ( nsContext ); this.prefixResolver = new JAXPPrefixResolver (nsContext);
} }
/** //-Override-
* <p>Returns the current namespace context.</p>
*
* @return Current Namespace context
*/
public NamespaceContext getNamespaceContext() { public NamespaceContext getNamespaceContext() {
return namespaceContext; return namespaceContext;
} }
private static Document d = null;
private DocumentBuilder getParser() {
try {
// we'd really like to cache those DocumentBuilders, but we can't because:
// 1. thread safety. parsers are not thread-safe, so at least
// we need one instance per a thread.
// 2. parsers are non-reentrant, so now we are looking at having a
// pool of parsers.
// 3. then the class loading issue. The look-up procedure of
// DocumentBuilderFactory.newInstance() depends on context class loader
// and system properties, which may change during the execution of JVM.
//
// so we really have to create a fresh DocumentBuilder every time we need one
// - KK
DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
dbf.setNamespaceAware( true );
dbf.setValidating( false );
return dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
// this should never happen with a well-behaving JAXP implementation.
throw new Error(e);
}
}
private XObject eval(String expression, Object contextItem)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression,
null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
if ( functionResolver != null ) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager );
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
} else {
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
}
XObject xobj = null;
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
// If item is null, then we will create a a Dummy contextNode
if ( contextItem instanceof Node ) {
xobj = xpath.execute (xpathSupport, (Node)contextItem,
prefixResolver );
} else {
xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
}
return xobj;
}
/** /**
* <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p> * Evaluate an {@code XPath} expression in the specified context.
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and <code>QName</code> resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
* {@link XPathConstants#NUMBER NUMBER},
* {@link XPathConstants#STRING STRING},
* {@link XPathConstants#BOOLEAN BOOLEAN},
* {@link XPathConstants#NODE NODE} or
* {@link XPathConstants#NODESET NODESET})
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
* <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression. * @param expression The XPath expression.
* @param item The starting context (node or node list, for example). * @param contextItem The starting context.
* @param returnType The desired return type. * @return an XObject as the result of evaluating the expression
* * @throws TransformerException if evaluating fails
* @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
*
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
*/ */
private XObject eval(String expression, Object contextItem)
throws TransformerException {
requireNonNull(expression, "XPath expression");
com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath(expression,
null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
return eval(contextItem, xpath);
}
//-Override-
public Object evaluate(String expression, Object item, QName returnType) public Object evaluate(String expression, Object item, QName returnType)
throws XPathExpressionException { throws XPathExpressionException {
if ( expression == null ) { //this check is necessary before calling eval to maintain binary compatibility
String fmsg = XSLMessages.createXPATHMessage( requireNonNull(expression, "XPath expression");
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, isSupported(returnType);
new Object[] {"XPath expression"} );
throw new NullPointerException ( fmsg );
}
if ( returnType == null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"returnType"} );
throw new NullPointerException ( fmsg );
}
// Checking if requested returnType is supported. returnType need to
// be defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
XObject resultObject = eval( expression, item ); XObject resultObject = eval(expression, item);
return getResultAsType( resultObject, returnType ); return getResultAsType(resultObject, returnType);
} catch ( java.lang.NullPointerException npe ) { } catch (java.lang.NullPointerException npe) {
// If VariableResolver returns null Or if we get // If VariableResolver returns null Or if we get
// NullPointerException at this stage for some other reason // NullPointerException at this stage for some other reason
// then we have to reurn XPathException // then we have to reurn XPathException
throw new XPathExpressionException ( npe ); throw new XPathExpressionException (npe);
} catch ( javax.xml.transform.TransformerException te ) { } catch (TransformerException te) {
Throwable nestedException = te.getException(); Throwable nestedException = te.getException();
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
throw (javax.xml.xpath.XPathFunctionException)nestedException; throw (javax.xml.xpath.XPathFunctionException)nestedException;
} else { } else {
// For any other exceptions we need to throw // For any other exceptions we need to throw
// XPathExpressionException ( as per spec ) // XPathExpressionException (as per spec)
throw new XPathExpressionException ( te ); throw new XPathExpressionException (te);
} }
} }
} }
private boolean isSupported( QName returnType ) { //-Override-
if ( ( returnType.equals( XPathConstants.STRING ) ) ||
( returnType.equals( XPathConstants.NUMBER ) ) ||
( returnType.equals( XPathConstants.BOOLEAN ) ) ||
( returnType.equals( XPathConstants.NODE ) ) ||
( returnType.equals( XPathConstants.NODESET ) ) ) {
return true;
}
return false;
}
private Object getResultAsType( XObject resultObject, QName returnType )
throws javax.xml.transform.TransformerException {
// XPathConstants.STRING
if ( returnType.equals( XPathConstants.STRING ) ) {
return resultObject.str();
}
// XPathConstants.NUMBER
if ( returnType.equals( XPathConstants.NUMBER ) ) {
return new Double ( resultObject.num());
}
// XPathConstants.BOOLEAN
if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
return new Boolean( resultObject.bool());
}
// XPathConstants.NODESET ---ORdered, UNOrdered???
if ( returnType.equals( XPathConstants.NODESET ) ) {
return resultObject.nodelist();
}
// XPathConstants.NODE
if ( returnType.equals( XPathConstants.NODE ) ) {
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return ni.nextNode();
}
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString()});
throw new IllegalArgumentException( fmsg );
}
/**
* <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
* {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param item The starting context (node or node list, for example).
*
* @return The <code>String</code> that is the result of evaluating the expression and
* converting the result to a <code>String</code>.
*
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
* @throws NullPointerException If <code>expression</code> is <code>null</code>.
*/
public String evaluate(String expression, Object item) public String evaluate(String expression, Object item)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( expression, item, XPathConstants.STRING ); return (String)this.evaluate(expression, item, XPathConstants.STRING);
} }
/** //-Override-
* <p>Compile an XPath expression for later evaluation.</p>
*
* <p>If <code>expression</code> contains any {@link XPathFunction}s,
* they must be available via the {@link XPathFunctionResolver}.
* An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code>
* cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
*
* <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
*
* @return Compiled XPath expression.
* @throws XPathExpressionException If <code>expression</code> cannot be compiled.
* @throws NullPointerException If <code>expression</code> is <code>null</code>.
*/
public XPathExpression compile(String expression) public XPathExpression compile(String expression)
throws XPathExpressionException { throws XPathExpressionException {
if ( expression == null ) { requireNonNull(expression, "XPath expression");
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPath expression"} );
throw new NullPointerException ( fmsg );
}
try { try {
com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null, com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null,
prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT ); prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
// Can have errorListener // Can have errorListener
XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath,
prefixResolver, functionResolver, variableResolver, prefixResolver, functionResolver, variableResolver,
featureSecureProcessing, useServiceMechanism, featureManager ); featureSecureProcessing, useServiceMechanism, featureManager);
return ximpl; return ximpl;
} catch ( javax.xml.transform.TransformerException te ) { } catch (TransformerException te) {
throw new XPathExpressionException ( te ) ; throw new XPathExpressionException (te) ;
} }
} }
//-Override-
/**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
* and return the result as the specified type.</p>
*
* <p>This method builds a data model for the {@link InputSource} and calls
* {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param source The input source of the document to evaluate over.
* @param returnType The desired return type.
*
* @return The <code>Object</code> that encapsulates the result of evaluating the expression.
*
* @throws XPathExpressionException If expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
* is <code>null</code>.
*/
public Object evaluate(String expression, InputSource source, public Object evaluate(String expression, InputSource source,
QName returnType) throws XPathExpressionException { QName returnType) throws XPathExpressionException {
// Checking validity of different parameters isSupported(returnType);
if( source== null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"source"} );
throw new NullPointerException ( fmsg );
}
if ( expression == null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"XPath expression"} );
throw new NullPointerException ( fmsg );
}
if ( returnType == null ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {"returnType"} );
throw new NullPointerException ( fmsg );
}
//Checking if requested returnType is supported.
//returnType need to be defined in XPathConstants
if ( !isSupported ( returnType ) ) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() } );
throw new IllegalArgumentException ( fmsg );
}
try { try {
Document document = getDocument(source);
Document document = getParser().parse( source ); XObject resultObject = eval(expression, document);
return getResultAsType(resultObject, returnType);
XObject resultObject = eval( expression, document ); } catch (TransformerException te) {
return getResultAsType( resultObject, returnType );
} catch ( SAXException e ) {
throw new XPathExpressionException ( e );
} catch( IOException e ) {
throw new XPathExpressionException ( e );
} catch ( javax.xml.transform.TransformerException te ) {
Throwable nestedException = te.getException(); Throwable nestedException = te.getException();
if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
throw (javax.xml.xpath.XPathFunctionException)nestedException; throw (javax.xml.xpath.XPathFunctionException)nestedException;
} else { } else {
throw new XPathExpressionException ( te ); throw new XPathExpressionException (te);
} }
} }
} }
//-Override-
/**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
* and return the result as a <code>String</code>.</p>
*
* <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
* <code>returnType</code> of {@link XPathConstants#STRING}.</p>
*
* <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
* for context item evaluation,
* variable, function and QName resolution and return type conversion.</p>
*
* <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param source The <code>InputSource</code> of the document to evaluate over.
*
* @return The <code>String</code> that is the result of evaluating the expression and
* converting the result to a <code>String</code>.
*
* @throws XPathExpressionException If expression cannot be evaluated.
* @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
*/
public String evaluate(String expression, InputSource source) public String evaluate(String expression, InputSource source)
throws XPathExpressionException { throws XPathExpressionException {
return (String)this.evaluate( expression, source, XPathConstants.STRING ); return (String)this.evaluate(expression, source, XPathConstants.STRING);
} }
/** //-Override-
* <p>Reset this <code>XPath</code> to its original configuration.</p>
*
* <p><code>XPath</code> is reset to the same state as when it was created with
* {@link XPathFactory#newXPath()}.
* <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
* thus saving resources associated with the creation of new <code>XPath</code>s.</p>
*
* <p>The reset <code>XPath</code> is not guaranteed to have the same
* {@link XPathFunctionResolver}, {@link XPathVariableResolver}
* or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
* It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>,
* <code>XPathVariableResolver</code>
* and <code>NamespaceContext</code>.</p>
*/
public void reset() { public void reset() {
this.variableResolver = this.origVariableResolver; this.variableResolver = this.origVariableResolver;
this.functionResolver = this.origFunctionResolver; this.functionResolver = this.origFunctionResolver;
this.namespaceContext = null; this.namespaceContext = null;
} }
//-Override-
public <T> T evaluateExpression(String expression, Object item, Class<T> type)
throws XPathExpressionException {
isSupportedClassType(type);
try {
XObject resultObject = eval(expression, item);
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
return getXPathResult(resultObject, type);
} else {
return XPathResultImpl.getValue(resultObject, type);
}
} catch (TransformerException te) {
throw new XPathExpressionException (te);
}
}
//-Override-
public XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
throws XPathExpressionException {
return evaluateExpression(expression, item, XPathEvaluationResult.class);
}
//-Override-
public <T> T evaluateExpression(String expression, InputSource source, Class<T> type)
throws XPathExpressionException {
Document document = getDocument(source);
return evaluateExpression(expression, document, type);
}
//-Override-
public XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
throws XPathExpressionException {
return evaluateExpression(expression, source, XPathEvaluationResult.class);
}
} }

View file

@ -0,0 +1,262 @@
/*
* 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 com.sun.org.apache.xpath.internal.jaxp;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.FeatureManager;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import java.io.IOException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathNodes;
import javax.xml.xpath.XPathVariableResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* This class contains several utility methods used by XPathImpl and
* XPathExpressionImpl
*/
class XPathImplUtil {
XPathFunctionResolver functionResolver;
XPathVariableResolver variableResolver;
JAXPPrefixResolver prefixResolver;
boolean useServiceMechanism = true;
// By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
boolean featureSecureProcessing = false;
FeatureManager featureManager;
/**
* Evaluate an XPath context using the internal XPath engine
* @param contextItem The XPath context
* @param xpath The internal XPath engine
* @return an XObject
* @throws javax.xml.transform.TransformerException If the expression cannot be evaluated.
*/
XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPathContext xpathSupport;
if (functionResolver != null) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager);
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext(jep);
} else {
xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
}
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
XObject xobj;
Node contextNode = (Node)contextItem;
// We always need to have a ContextNode with Xalan XPath implementation
// To allow simple expression evaluation like 1+1 we are setting
// dummy Document as Context Node
if (contextNode == null) {
xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
} else {
xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
}
return xobj;
}
/**
* Parse the input source and return a Document.
* @param source The {@code InputSource} of the document
* @return a DOM Document
* @throws XPathExpressionException if there is an error parsing the source.
*/
Document getDocument(InputSource source)
throws XPathExpressionException {
requireNonNull(source, "Source");
try {
// we'd really like to cache those DocumentBuilders, but we can't because:
// 1. thread safety. parsers are not thread-safe, so at least
// we need one instance per a thread.
// 2. parsers are non-reentrant, so now we are looking at having a
// pool of parsers.
// 3. then the class loading issue. The look-up procedure of
// DocumentBuilderFactory.newInstance() depends on context class loader
// and system properties, which may change during the execution of JVM.
//
// so we really have to create a fresh DocumentBuilder every time we need one
// - KK
DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
dbf.setNamespaceAware(true);
dbf.setValidating(false);
return dbf.newDocumentBuilder().parse(source);
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new XPathExpressionException (e);
}
}
/**
* Get result depending on the QName type defined in XPathConstants
* @param resultObject the result of an evaluation
* @param returnType the return type
* @return result per the return type
* @throws TransformerException if the result can not be converted to
* the specified return type.
*/
Object getResultAsType(XObject resultObject, QName returnType)
throws TransformerException {
// XPathConstants.STRING
if (returnType.equals(XPathConstants.STRING)) {
return resultObject.str();
}
// XPathConstants.NUMBER
if (returnType.equals(XPathConstants.NUMBER)) {
return resultObject.num();
}
// XPathConstants.BOOLEAN
if (returnType.equals(XPathConstants.BOOLEAN)) {
return resultObject.bool();
}
// XPathConstants.NODESET ---ORdered, UNOrdered???
if (returnType.equals(XPathConstants.NODESET)) {
return resultObject.nodelist();
}
// XPathConstants.NODE
if (returnType.equals(XPathConstants.NODE)) {
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return ni.nextNode();
}
// If isSupported check is already done then the execution path
// shouldn't come here. Being defensive
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString()});
throw new IllegalArgumentException (fmsg);
}
/**
* Construct an XPathExpressionResult object based on the result of the
* evaluation and cast to the specified class type.
* @param <T> The class type
* @param resultObject the result of an evaluation
* @param type The class type expected to be returned by the XPath expression.
* @return an instance of the specified type or null if the XObject returned
* an UNKNOWN object type.
* @throws TransformerException if there is an error converting the result
* to the specified type. It's unlikely to happen. This is mostly needed
* by the internal XPath engine.
*/
<T> T getXPathResult(XObject resultObject, Class<T> type)
throws TransformerException {
int resultType = resultObject.getType();
switch (resultType) {
case XObject.CLASS_BOOLEAN :
return type.cast(new XPathResultImpl<>(resultObject, Boolean.class));
case XObject.CLASS_NUMBER :
return type.cast(new XPathResultImpl<>(resultObject, Double.class));
case XObject.CLASS_STRING :
return type.cast(new XPathResultImpl<>(resultObject, String.class));
case XObject.CLASS_NODESET :
return type.cast(new XPathResultImpl<>(resultObject, XPathNodes.class));
case XObject.CLASS_RTREEFRAG : //NODE
return type.cast(new XPathResultImpl<>(resultObject, Node.class));
}
return null;
}
/**
* Check whether or not the specified type is supported
* @param <T> The class type
* @param type The type to be checked
* @throws IllegalArgumentException if the type is not supported
*/
<T> void isSupportedClassType(Class<T> type) {
requireNonNull(type, "The class type");
if (type.isAssignableFrom(Boolean.class) ||
type.isAssignableFrom(Double.class) ||
type.isAssignableFrom(Integer.class) ||
type.isAssignableFrom(Long.class) ||
type.isAssignableFrom(String.class) ||
type.isAssignableFrom(XPathNodes.class) ||
type.isAssignableFrom(Node.class) ||
type.isAssignableFrom(XPathEvaluationResult.class)) {
return;
}
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { type.toString() });
throw new IllegalArgumentException (fmsg);
}
/**
* Check if the requested returnType is supported.
* @param returnType the return type
* @throws IllegalArgumentException if the return type is not supported
*/
void isSupported(QName returnType) {
requireNonNull(returnType, "returnType");
if (returnType.equals(XPathConstants.STRING) ||
returnType.equals(XPathConstants.NUMBER) ||
returnType.equals(XPathConstants.BOOLEAN) ||
returnType.equals(XPathConstants.NODE) ||
returnType.equals(XPathConstants.NODESET)) {
return;
}
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
new Object[] { returnType.toString() });
throw new IllegalArgumentException (fmsg);
}
/**
* Checks that the specified parameter is not {@code null}.
*
* @param <T> the type of the reference
* @param param the parameter to check for nullity
* @param paramName the parameter name
* @throws NullPointerException if {@code param} is {@code null}
*/
<T> void requireNonNull(T param, String paramName) {
if (param == null) {
String fmsg = XSLMessages.createXPATHMessage(
XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
new Object[] {paramName});
throw new NullPointerException (fmsg);
}
}
}

View file

@ -0,0 +1,93 @@
/*
* 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 com.sun.org.apache.xpath.internal.jaxp;
import java.util.Iterator;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathNodes;
import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This class implements XPathNodes that represents a set of nodes selected by
* evaluating an expression.
*/
public class XPathNodesImpl implements XPathNodes {
Class<Node> elementType;
NodeList nodeList = null;
public XPathNodesImpl(NodeList nodeList, Class<Node> elementType) {
this.nodeList = nodeList;
this.elementType = elementType;
}
@Override
public Iterator<Node> iterator() {
return new NodeSetIterator<>(elementType);
}
class NodeSetIterator<E> implements Iterator<E> {
int currentIndex;
Class<E> elementType;
NodeSetIterator(Class<E> elementType) {
this.elementType = elementType;
}
public boolean hasNext() {
if (nodeList != null) {
return currentIndex < nodeList.getLength();
}
return false;
}
public E next() {
if (nodeList != null && nodeList.getLength() > 0) {
return elementType.cast(nodeList.item(currentIndex++));
}
return null;
}
}
@Override
public int size() {
if (nodeList != null) {
return nodeList.getLength();
}
return 0;
}
@Override
public Node get(int index) throws XPathException {
if (index <0 || index >= size()) {
throw new IndexOutOfBoundsException("Index " + index + " is out of bounds");
}
if (nodeList != null) {
return nodeList.item(index);
}
return null;
}
}

View file

@ -0,0 +1,201 @@
/*
* 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 com.sun.org.apache.xpath.internal.jaxp;
import com.sun.org.apache.xpath.internal.objects.XObject;
import java.util.Objects;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathNodes;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.NodeIterator;
/**
* This is the implementation of XPathEvaluationResult that represents the
* result of the evaluation of an XPath expression within the context of a
* particular node.
*/
class XPathResultImpl<T> implements XPathEvaluationResult<T> {
XObject resultObject;
int resultType;
Class<T> type;
XPathResultType mapToType;
NodeList nodeList = null;
int currentIndex;
Node currentNode;
boolean boolValue = false;
Node node = null;
double numValue;
String strValue;
/**
* Construct an XPathEvaluationResult object.
*
* @param resultObject internal XPath result object
* @param type class type
* @throws TransformerException if there is an error reading the XPath
* result.
*/
public XPathResultImpl(XObject resultObject, Class<T> type)
throws TransformerException {
this.resultObject = resultObject;
resultType = resultObject.getType();
this.type = type;
getResult(resultObject);
}
/**
* Return the result type as an enum specified by {@code XPathResultType}
* @return the result type
*/
@Override
public XPathResultType type() {
return mapToType;
}
/**
* Returns the value of the result as the type &lt;T&gt; specified for the class.
*
* @return The value of the result.
*/
@Override
public T value() {
Objects.requireNonNull(type);
try {
return getValue(resultObject, type);
} catch (TransformerException ex) {
throw new RuntimeException(ex);
}
}
/**
* Read the XObject and set values in accordance with the result type
* @param resultObject internal XPath result object
* @throws TransformerException if there is an error reading the XPath
* result.
*/
private void getResult(XObject resultObject) throws TransformerException {
switch (resultType) {
case XObject.CLASS_BOOLEAN:
boolValue = resultObject.bool();
mapToType = XPathResultType.BOOLEAN;
break;
case XObject.CLASS_NUMBER:
numValue = resultObject.num();
mapToType = XPathResultType.NUMBER;
break;
case XObject.CLASS_STRING:
strValue = resultObject.str();
mapToType = XPathResultType.STRING;
break;
case XObject.CLASS_NODESET:
mapToType = XPathResultType.NODESET;
nodeList = resultObject.nodelist();
break;
case XObject.CLASS_RTREEFRAG: //NODE
mapToType = XPathResultType.NODE;
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
node = ni.nextNode();
break;
}
}
/**
* Read the internal result object and return the value in accordance with
* the type specified.
*
* @param <T> The expected class type.
* @param resultObject internal XPath result object
* @param type the class type
* @return The value of the result, null in case of unexpected type.
* @throws TransformerException if there is an error reading the XPath
* result.
*/
static <T> T getValue(XObject resultObject, Class<T> type) throws TransformerException {
Objects.requireNonNull(type);
if (type.isAssignableFrom(XPathEvaluationResult.class)) {
return type.cast(new XPathResultImpl<T>(resultObject, type));
}
int resultType = classToInternalType(type);
switch (resultType) {
case XObject.CLASS_BOOLEAN:
return type.cast(resultObject.bool());
case XObject.CLASS_NUMBER:
if (Double.class.isAssignableFrom(type)) {
return type.cast(resultObject.num());
} else if (Integer.class.isAssignableFrom(type)) {
return type.cast((int)resultObject.num());
} else if (Long.class.isAssignableFrom(type)) {
return type.cast((long)resultObject.num());
}
/*
This is to suppress warnings. By the current specification,
among numeric types, only Double, Integer and Long are supported.
*/
break;
case XObject.CLASS_STRING:
return type.cast(resultObject.str());
case XObject.CLASS_NODESET:
XPathNodes nodeSet = new XPathNodesImpl(resultObject.nodelist(),
Node.class);
return type.cast(nodeSet);
case XObject.CLASS_RTREEFRAG: //NODE
NodeIterator ni = resultObject.nodeset();
//Return the first node, or null
return type.cast(ni.nextNode());
}
return null;
}
/**
* Map the specified class type to the internal result type
*
* @param <T> The expected class type.
* @param type the class type
* @return the internal XObject type.
*/
static <T> int classToInternalType(Class<T> type) {
if (type.isAssignableFrom(Boolean.class)) {
return XObject.CLASS_BOOLEAN;
} else if (Number.class.isAssignableFrom(type)) {
return XObject.CLASS_NUMBER;
} else if (type.isAssignableFrom(String.class)) {
return XObject.CLASS_STRING;
} else if (type.isAssignableFrom(XPathNodes.class)) {
return XObject.CLASS_NODESET;
} else if (type.isAssignableFrom(Node.class)) {
return XObject.CLASS_RTREEFRAG;
}
return XObject.CLASS_NULL;
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,12 +25,12 @@
package javax.xml.xpath; package javax.xml.xpath;
import org.xml.sax.InputSource;
import javax.xml.namespace.QName;
import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import org.xml.sax.InputSource;
/** /**
* <p><code>XPath</code> provides access to the XPath evaluation environment and expressions.</p> * {@code XPath} provides access to the XPath evaluation environment and expressions.
* *
* <a name="XPath-evaluation"/> * <a name="XPath-evaluation"/>
* <table border="1" cellpadding="2"> * <table border="1" cellpadding="2">
@ -39,7 +39,6 @@ import javax.xml.namespace.NamespaceContext;
* <th colspan="2">Evaluation of XPath Expressions.</th> * <th colspan="2">Evaluation of XPath Expressions.</th>
* </tr> * </tr>
* </thead> * </thead>
* <tbody>
* <tr> * <tr>
* <td>context</td> * <td>context</td>
* <td> * <td>
@ -55,8 +54,8 @@ import javax.xml.namespace.NamespaceContext;
* If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver} * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}
* set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}. * set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}.
* An {@link XPathExpressionException} is raised if the variable resolver is undefined or * An {@link XPathExpressionException} is raised if the variable resolver is undefined or
* the resolver returns <code>null</code> for the variable. * the resolver returns {@code null} for the variable.
* The value of a variable must be immutable through the course of any single evaluation.</p> * The value of a variable must be immutable through the course of any single evaluation.
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
@ -65,7 +64,7 @@ import javax.xml.namespace.NamespaceContext;
* If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver} * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}
* set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}. * set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}.
* An {@link XPathExpressionException} is raised if the function resolver is undefined or * An {@link XPathExpressionException} is raised if the function resolver is undefined or
* the function resolver returns <code>null</code> for the function.</p> * the function resolver returns {@code null} for the function.
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
@ -80,7 +79,7 @@ import javax.xml.namespace.NamespaceContext;
* <td> * <td>
* This result of evaluating an expression is converted to an instance of the desired return type. * This result of evaluating an expression is converted to an instance of the desired return type.
* Valid return types are defined in {@link XPathConstants}. * Valid return types are defined in {@link XPathConstants}.
* Conversion to the return type follows XPath conversion rules.</p> * Conversion to the return type follows XPath conversion rules.
* </td> * </td>
* </tr> * </tr>
* </table> * </table>
@ -88,9 +87,9 @@ import javax.xml.namespace.NamespaceContext;
* <p>An XPath object is not thread-safe and not reentrant. * <p>An XPath object is not thread-safe and not reentrant.
* In other words, it is the application's responsibility to make * In other words, it is the application's responsibility to make
* sure that one {@link XPath} object is not used from * sure that one {@link XPath} object is not used from
* more than one thread at any given time, and while the <code>evaluate</code> * more than one thread at any given time, and while the {@code evaluate}
* method is invoked, applications may not recursively call * method is invoked, applications may not recursively call
* the <code>evaluate</code> method. * the {@code evaluate} method.
* <p> * <p>
* *
* @author <a href="Norman.Walsh@Sun.com">Norman Walsh</a> * @author <a href="Norman.Walsh@Sun.com">Norman Walsh</a>
@ -100,191 +99,189 @@ import javax.xml.namespace.NamespaceContext;
*/ */
public interface XPath { public interface XPath {
/**
* <p>Reset this <code>XPath</code> to its original configuration.</p>
*
* <p><code>XPath</code> is reset to the same state as when it was created with
* {@link XPathFactory#newXPath()}.
* <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
* thus saving resources associated with the creation of new <code>XPath</code>s.</p>
*
* <p>The reset <code>XPath</code> is not guaranteed to have the same {@link XPathFunctionResolver}, {@link XPathVariableResolver}
* or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
* It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>, <code>XPathVariableResolver</code>
* and <code>NamespaceContext</code>.</p>
*/
public void reset();
/** /**
* <p>Establish a variable resolver.</p> * Reset this {@code XPath} to its original configuration.
* *
* <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p> * <p>{@code XPath} is reset to the same state as when it was created with
* {@link XPathFactory#newXPath()}.
* {@code reset()} is designed to allow the reuse of existing {@code XPath}s
* thus saving resources associated with the creation of new {@code XPath}s.
*
* <p>The reset {@code XPath} is not guaranteed to have the same
* {@link XPathFunctionResolver}, {@link XPathVariableResolver}
* or {@link NamespaceContext} {@code Object}s, e.g. {@link Object#equals(Object obj)}.
* It is guaranteed to have a functionally equal {@code XPathFunctionResolver},
* {@code XPathVariableResolver} and {@code NamespaceContext}.
*/
public void reset();
/**
* Establish a variable resolver.
*
* <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
* *
* @param resolver Variable resolver. * @param resolver Variable resolver.
* *
* @throws NullPointerException If <code>resolver</code> is <code>null</code>. * @throws NullPointerException If {@code resolver} is {@code null}.
*/ */
public void setXPathVariableResolver(XPathVariableResolver resolver); public void setXPathVariableResolver(XPathVariableResolver resolver);
/** /**
* <p>Return the current variable resolver.</p> * Return the current variable resolver.
* *
* <p><code>null</code> is returned in no variable resolver is in effect.</p> * <p>{@code null} is returned in no variable resolver is in effect.
* *
* @return Current variable resolver. * @return Current variable resolver.
*/ */
public XPathVariableResolver getXPathVariableResolver(); public XPathVariableResolver getXPathVariableResolver();
/** /**
* <p>Establish a function resolver.</p> * Establish a function resolver.
* *
* <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p> * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
* *
* @param resolver XPath function resolver. * @param resolver XPath function resolver.
* *
* @throws NullPointerException If <code>resolver</code> is <code>null</code>. * @throws NullPointerException If {@code resolver} is {@code null}.
*/ */
public void setXPathFunctionResolver(XPathFunctionResolver resolver); public void setXPathFunctionResolver(XPathFunctionResolver resolver);
/** /**
* <p>Return the current function resolver.</p> * Return the current function resolver.
* * <p>
* <p><code>null</code> is returned in no function resolver is in effect.</p> * {@code null} is returned in no function resolver is in effect.
* *
* @return Current function resolver. * @return Current function resolver.
*/ */
public XPathFunctionResolver getXPathFunctionResolver(); public XPathFunctionResolver getXPathFunctionResolver();
/** /**
* <p>Establish a namespace context.</p> * Establish a namespace context.
* *
* <p>A <code>NullPointerException</code> is thrown if <code>nsContext</code> is <code>null</code>.</p> * <p>A {@code NullPointerException} is thrown if {@code nsContext} is {@code null}.
* *
* @param nsContext Namespace context to use. * @param nsContext Namespace context to use.
* *
* @throws NullPointerException If <code>nsContext</code> is <code>null</code>. * @throws NullPointerException If {@code nsContext} is {@code null}.
*/ */
public void setNamespaceContext(NamespaceContext nsContext); public void setNamespaceContext(NamespaceContext nsContext);
/** /**
* <p>Return the current namespace context.</p> * Return the current namespace context.
* *
* <p><code>null</code> is returned in no namespace context is in effect.</p> * <p>{@code null} is returned in no namespace context is in effect.
* *
* @return Current Namespace context. * @return Current Namespace context.
*/ */
public NamespaceContext getNamespaceContext(); public NamespaceContext getNamespaceContext();
/** /**
* <p>Compile an XPath expression for later evaluation.</p> * Compile an XPath expression for later evaluation.
* *
* <p>If <code>expression</code> contains any {@link XPathFunction}s, * <p>If {@code expression} contains any {@link XPathFunction}s,
* they must be available via the {@link XPathFunctionResolver}. * they must be available via the {@link XPathFunctionResolver}.
* An {@link XPathExpressionException} will be thrown if the * An {@link XPathExpressionException} will be thrown if the
* <code>XPathFunction</code> * {@code XPathFunction}
* cannot be resovled with the <code>XPathFunctionResolver</code>.</p> * cannot be resovled with the {@code XPathFunctionResolver}.
* *
* <p>If <code>expression</code> contains any variables, the * <p>If {@code expression} contains any variables, the
* {@link XPathVariableResolver} in effect * {@link XPathVariableResolver} in effect
* <strong>at compile time</strong> will be used to resolve them.</p> * <strong>at compile time</strong> will be used to resolve them.
*
* <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* *
* @return Compiled XPath expression. * @return Compiled XPath expression.
* @throws XPathExpressionException If <code>expression</code> cannot be compiled. * @throws XPathExpressionException If {@code expression} cannot be compiled.
* @throws NullPointerException If <code>expression</code> is <code>null</code>. * @throws NullPointerException If {@code expression} is {@code null}.
*/ */
public XPathExpression compile(String expression) public XPathExpression compile(String expression)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p> * Evaluate an {@code XPath} expression in the specified context and
* return the result as the specified type.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>
* variable, function and <code>QName</code> resolution and return type conversion.</p> * See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a>
* for context item evaluation, variable, function and {@code QName} resolution
* and return type conversion.
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
* *
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} ( * @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @param expression The XPath expression.
* @param item The context the XPath expression will be evaluated in.
* @param returnType The result type expected to be returned by the XPath expression.
*
* @return The result of evaluating an XPath expression as an {@code Object} of {@code returnType}.
*
* @throws XPathExpressionException If {@code expression} cannot be evaluated.
* @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants} (
* {@link XPathConstants#NUMBER NUMBER}, * {@link XPathConstants#NUMBER NUMBER},
* {@link XPathConstants#STRING STRING}, * {@link XPathConstants#STRING STRING},
* {@link XPathConstants#BOOLEAN BOOLEAN}, * {@link XPathConstants#BOOLEAN BOOLEAN},
* {@link XPathConstants#NODE NODE} or * {@link XPathConstants#NODE NODE} or
* {@link XPathConstants#NODESET NODESET}) * {@link XPathConstants#NODESET NODESET}).
* then an <code>IllegalArgumentException</code> is thrown.</p> * @throws NullPointerException If {@code expression or returnType} is {@code null}.
*
* <p>If a <code>null</code> value is provided for
* <code>item</code>, an empty document will be used for the
* context.
* If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
* <code>NullPointerException</code> is thrown.</p>
*
* @param expression The XPath expression.
* @param item The starting context (a node, for example).
* @param returnType The desired return type.
*
* @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
*
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
*/ */
public Object evaluate(String expression, Object item, QName returnType) public Object evaluate(String expression, Object item, QName returnType)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p> * Evaluate an XPath expression in the specified context and return the result as a {@code String}.
* *
* <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a {@code returnType} of
* {@link XPathConstants#STRING}.</p> * {@link XPathConstants#STRING}.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.
* *
* <p>If a <code>null</code> value is provided for * <p>
* <code>item</code>, an empty document will be used for the * The parameter {@code item} represents the context the XPath expression
* context. * will be operated on. The type of the context is implementation-dependent.
* If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p> * If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* @param item The starting context (a node, for example). * @param item The context the XPath expression will be evaluated in.
* *
* @return The <code>String</code> that is the result of evaluating the expression and * @return The result of evaluating an XPath expression as a {@code String}.
* converting the result to a <code>String</code>.
* *
* @throws XPathExpressionException If <code>expression</code> cannot be evaluated. * @throws XPathExpressionException If {@code expression} cannot be evaluated.
* @throws NullPointerException If <code>expression</code> is <code>null</code>. * @throws NullPointerException If {@code expression} is {@code null}.
*/ */
public String evaluate(String expression, Object item) public String evaluate(String expression, Object item)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> * Evaluate an XPath expression in the context of the specified {@code InputSource}
* and return the result as the specified type.</p> * and return the result as the specified type.
* *
* <p>This method builds a data model for the {@link InputSource} and calls * <p>This method builds a data model for the {@link InputSource} and calls
* {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p> * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.
*
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p>
*
* <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* @param source The input source of the document to evaluate over. * @param source The input source of the document to evaluate over.
* @param returnType The desired return type. * @param returnType The desired return type.
* *
* @return The <code>Object</code> that encapsulates the result of evaluating the expression. * @return The {@code Object} that encapsulates the result of evaluating the expression.
* *
* @throws XPathExpressionException If expression cannot be evaluated. * @throws XPathExpressionException If expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code> * @throws NullPointerException If {@code expression, source or returnType} is {@code null}.
* is <code>null</code>.
*/ */
public Object evaluate( public Object evaluate(
String expression, String expression,
@ -293,27 +290,209 @@ public interface XPath {
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> * Evaluate an XPath expression in the context of the specified {@code InputSource}
* and return the result as a <code>String</code>.</p> * and return the result as a {@code String}.
* *
* <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
* <code>returnType</code> of {@link XPathConstants#STRING}.</p> * {@code returnType} of {@link XPathConstants#STRING}.
* *
* <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.
*
* <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
* then a <code>NullPointerException</code> is thrown.</p>
* *
* @param expression The XPath expression. * @param expression The XPath expression.
* @param source The <code>InputSource</code> of the document to evaluate over. * @param source The {@code InputSource} of the document to evaluate over.
* *
* @return The <code>String</code> that is the result of evaluating the expression and * @return The {@code String} that is the result of evaluating the expression and
* converting the result to a <code>String</code>. * converting the result to a {@code String}.
* *
* @throws XPathExpressionException If expression cannot be evaluated. * @throws XPathExpressionException If expression cannot be evaluated.
* @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>. * @throws NullPointerException If {@code expression or source} is {@code null}.
*/ */
public String evaluate(String expression, InputSource source) public String evaluate(String expression, InputSource source)
throws XPathExpressionException; throws XPathExpressionException;
/**
* Evaluate an XPath expression in the specified context and return
* the result with the type specified through the {@code class type}
*
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* (T)evaluate(expression, item,
* XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param expression The XPath expression.
* @param item The context the XPath expression will be evaluated in.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType},
* or XPathEvaluationResult is specified as the type but an implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
* @throws NullPointerException If {@code expression or type} is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(String expression, Object item, Class<T> type)
throws XPathExpressionException {
return type.cast(evaluate(expression, item,
XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate an XPath expression in the specified context. This is equivalent to
* calling {@link #evaluateExpression(String expression, Object item, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(expression, item, XPathEvaluationResult.class);
* }</pre>
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* evaluateExpression(expression, item, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param expression The XPath expression.
* @param item The context the XPath expression will be evaluated in.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
* @throws NullPointerException If {@code expression} is {@code null}.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
throws XPathExpressionException
{
return evaluateExpression(expression, item, XPathEvaluationResult.class);
}
/**
* Evaluate an XPath expression in the context of the specified {@code source}
* and return the result as specified.
* <p>
* This method builds a data model for the {@link InputSource} and calls
* {@link #evaluateExpression(String expression, Object item, Class type)}
* on the resulting document object. The data model is usually
* {@link org.w3c.dom.Document}
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
(T)evaluate(expression, source,
XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param expression The XPath expression.
* @param source The input source of the document to evaluate over.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
* implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
* @throws NullPointerException If {@code expression, source or type}is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(String expression, InputSource source, Class<T> type)
throws XPathExpressionException
{
return type.cast(evaluate(expression, source,
XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate an XPath expression in the specified context. This is equivalent to
* calling {@link #evaluateExpression(String expression, Object item, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(expression, item, XPathEvaluationResult.class);
* }</pre>
* <p>
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* evaluateExpression(expression, source, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param expression The XPath expression.
* @param source The input source of the document to evaluate over.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
* @throws NullPointerException If {@code expression or source} is {@code null}.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
throws XPathExpressionException
{
return evaluateExpression(expression, source, XPathEvaluationResult.class);
}
} }

View file

@ -0,0 +1,130 @@
/*
* 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 javax.xml.xpath;
import java.util.Objects;
import javax.xml.namespace.QName;
import org.w3c.dom.Node;
/**
* The {@code XPathEvaluationResult} interface represents the result of the
* evaluation of an XPath expression within the context of a particular node.
* The evaluation of an XPath expression can result in various result types as
* defined in XML Path Language (XPath) Version 1.0.
* <p>
*
* @param <T> the object type returned by the XPath evaluation.
* @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version
* 1.0</a>
*
* @since 1.9
*/
public interface XPathEvaluationResult<T> {
/**
* XPathResultType represents possible return types of an XPath evaluation.
* Provided as an enum type, it allows the use of switch statement. At the
* same time, a mapping is provided between the original QName types in
* {@link XPathConstants} and class types used in the generic methods.
*/
public static enum XPathResultType {
/**
* Any type that represents any of the 5 other types listed below.
* Maps to {@link XPathEvaluationResult}.
*/
ANY(new QName("http://www.w3.org/1999/XSL/Transform", "any"), XPathEvaluationResult.class),
/**
* The XPath 1.0 boolean data type. Maps to Java {@link Boolean}.
*/
BOOLEAN(XPathConstants.BOOLEAN, Boolean.class),
/**
* The XPath 1.0 Number data type. Maps to Java {@link Number}. Of the
* subtypes of Number, only Double, Integer and Long are required.
*/
NUMBER(XPathConstants.NUMBER, Number.class),
/**
* The XPath 1.0 String data type. Maps to Java {@link String}.
*/
STRING(XPathConstants.STRING, String.class),
/**
* The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.NodeList}.
*/
NODESET(XPathConstants.NODESET, XPathNodes.class),
/**
* The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.Node}.
*/
NODE(XPathConstants.NODE, Node.class);
final QName qnameType;
final Class<?> clsType;
XPathResultType(QName qnameType, Class<?> clsType) {
this.qnameType = qnameType;
this.clsType = clsType;
}
/**
* Compares this type to the specified class type.
* @param clsType class type
* @return true if the argument is not null and is a class type that
* matches that this type represents, false otherwise.
*/
private boolean equalsClassType(Class<?> clsType) {
Objects.nonNull(clsType);
if (clsType.isAssignableFrom(this.clsType)) {
return true;
}
return false;
}
/**
* Returns the QName type as specified in {@link XPathConstants} that
* corresponds to the specified class type.
* @param clsType a class type that the enum type supports
* @return the QName type that matches with the specified class type,
* null if there is no match
*/
static public QName getQNameType(Class<?> clsType) {
for (XPathResultType type : XPathResultType.values()) {
if (type.equalsClassType(clsType)) {
return type.qnameType;
}
}
return null;
}
}
/**
* Return the result type as an enum specified by {@code XPathResultType}
* @return the result type
*/
public XPathResultType type();
/**
* Returns the value of the result as the type &lt;T&gt; specified for the class.
*
* @return The value of the result.
*/
public T value();
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,11 +25,11 @@
package javax.xml.xpath; package javax.xml.xpath;
import org.xml.sax.InputSource;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.xml.sax.InputSource;
/** /**
* <p><code>XPathExpression</code> provides access to compiled XPath expressions.</p> * <p>{@code XPathExpression} provides access to compiled XPath expressions.</p>
* *
* <a name="XPathExpression-evaluation"/> * <a name="XPathExpression-evaluation"/>
* <table border="1" cellpadding="2"> * <table border="1" cellpadding="2">
@ -53,7 +53,7 @@ import javax.xml.namespace.QName;
* <td> * <td>
* If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}. * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}.
* An {@link XPathExpressionException} is raised if the variable resolver is undefined or * An {@link XPathExpressionException} is raised if the variable resolver is undefined or
* the resolver returns <code>null</code> for the variable. * the resolver returns {@code null} for the variable.
* The value of a variable must be immutable through the course of any single evaluation.</p> * The value of a variable must be immutable through the course of any single evaluation.</p>
* </td> * </td>
* </tr> * </tr>
@ -62,7 +62,7 @@ import javax.xml.namespace.QName;
* <td> * <td>
* If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}. * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}.
* An {@link XPathExpressionException} is raised if the function resolver is undefined or * An {@link XPathExpressionException} is raised if the function resolver is undefined or
* the function resolver returns <code>null</code> for the function.</p> * the function resolver returns {@code null} for the function.</p>
* </td> * </td>
* </tr> * </tr>
* <tr> * <tr>
@ -84,9 +84,9 @@ import javax.xml.namespace.QName;
* <p>An XPath expression is not thread-safe and not reentrant. * <p>An XPath expression is not thread-safe and not reentrant.
* In other words, it is the application's responsibility to make * In other words, it is the application's responsibility to make
* sure that one {@link XPathExpression} object is not used from * sure that one {@link XPathExpression} object is not used from
* more than one thread at any given time, and while the <code>evaluate</code> * more than one thread at any given time, and while the {@code evaluate}
* method is invoked, applications may not recursively call * method is invoked, applications may not recursively call
* the <code>evaluate</code> method. * the {@code evaluate} method.
* <p> * <p>
* *
* @author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a> * @author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a>
@ -96,50 +96,56 @@ import javax.xml.namespace.QName;
*/ */
public interface XPathExpression { public interface XPathExpression {
/** /**
* <p>Evaluate the compiled XPath expression in the specified context and return the result as the specified type.</p> * <p>Evaluate the compiled XPath expression in the specified context and return the result as the specified type.</p>
* *
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants}, * <p>
* then an <code>IllegalArgumentException</code> is thrown.</p> * The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
* *
* <p>If a <code>null</code> value is provided for * @implNote
* <code>item</code>, an empty document will be used for the * The type of the context is usually {@link org.w3c.dom.Node}.
* context.
* If <code>returnType</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
* *
* @param item The starting context (a node, for example). * @param item The context the XPath expression will be evaluated in.
* @param returnType The desired return type. * @param returnType The result type expected to be returned by the XPath expression.
* *
* @return The <code>Object</code> that is the result of evaluating the expression and converting the result to * @return The {@code Object} that is the result of evaluating the expression and converting the result to
* <code>returnType</code>. * {@code returnType}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>returnType</code> is <code>null</code>. * @throws NullPointerException If {@code returnType} is {@code null}.
*/ */
public Object evaluate(Object item, QName returnType) public Object evaluate(Object item, QName returnType)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate the compiled XPath expression in the specified context and return the result as a <code>String</code>.</p> * <p>Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}.</p>
* *
* <p>This method calls {@link #evaluate(Object item, QName returnType)} with a <code>returnType</code> of * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a {@code returnType} of
* {@link XPathConstants#STRING}.</p> * {@link XPathConstants#STRING}.</p>
* *
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If a <code>null</code> value is provided for * <p>
* <code>item</code>, an empty document will be used for the * The parameter {@code item} represents the context the XPath expression
* context. * will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
* *
* @param item The starting context (a node, for example). * @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
* *
* @return The <code>String</code> that is the result of evaluating the expression and converting the result to a * @param item The context the XPath expression will be evaluated in.
* <code>String</code>. *
* @return The result of evaluating an XPath expression as a {@code String}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
*/ */
@ -147,7 +153,7 @@ public interface XPathExpression {
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as the * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as the
* specified type.</p> * specified type.</p>
* *
* <p>This method builds a data model for the {@link InputSource} and calls * <p>This method builds a data model for the {@link InputSource} and calls
@ -156,45 +162,225 @@ public interface XPathExpression {
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants}, * <p>If {@code returnType} is not one of the types defined in {@link XPathConstants},
* then an <code>IllegalArgumentException</code> is thrown.</p> * then an {@code IllegalArgumentException} is thrown.</p>
* *
* <p>If <code>source</code> or <code>returnType</code> is <code>null</code>, * <p>If {@code source} or {@code returnType} is {@code null},
* then a <code>NullPointerException</code> is thrown.</p> * then a {@code NullPointerException} is thrown.</p>
* *
* @param source The <code>InputSource</code> of the document to evaluate over. * @param source The {@code InputSource} of the document to evaluate over.
* @param returnType The desired return type. * @param returnType The desired return type.
* *
* @return The <code>Object</code> that is the result of evaluating the expression and converting the result to * @return The {@code Object} that is the result of evaluating the expression and converting the result to
* <code>returnType</code>. * {@code returnType}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
* @throws NullPointerException If <code>source</code> or <code>returnType</code> is <code>null</code>. * @throws NullPointerException If {@code source or returnType} is {@code null}.
*/ */
public Object evaluate(InputSource source, QName returnType) public Object evaluate(InputSource source, QName returnType)
throws XPathExpressionException; throws XPathExpressionException;
/** /**
* <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as a
* <code>String</code>.</p> * {@code String}.</p>
* *
* <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a {@code returnType} of
* {@link XPathConstants#STRING}.</p> * {@link XPathConstants#STRING}.</p>
* *
* <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation, * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
* variable, function and QName resolution and return type conversion.</p> * variable, function and QName resolution and return type conversion.</p>
* *
* <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p> * <p>If {@code source} is {@code null}, then a {@code NullPointerException} is thrown.</p>
* *
* @param source The <code>InputSource</code> of the document to evaluate over. * @param source The {@code InputSource} of the document to evaluate over.
* *
* @return The <code>String</code> that is the result of evaluating the expression and converting the result to a * @return The {@code String} that is the result of evaluating the expression and converting the result to a
* <code>String</code>. * {@code String}.
* *
* @throws XPathExpressionException If the expression cannot be evaluated. * @throws XPathExpressionException If the expression cannot be evaluated.
* @throws NullPointerException If <code>source</code> is <code>null</code>. * @throws NullPointerException If {@code source} is {@code null}.
*/ */
public String evaluate(InputSource source) public String evaluate(InputSource source)
throws XPathExpressionException; throws XPathExpressionException;
/**
* Evaluate the compiled XPath expression in the specified context, and return
* the result with the type specified through the {@code class type}.
*
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* (T)evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param item The context the XPath expression will be evaluated in.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
* implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
* @throws NullPointerException If {@code type} is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(Object item, Class<T> type)
throws XPathExpressionException
{
return type.cast(evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate the compiled XPath expression in the specified context. This is
* equivalent to calling {@link #evaluateExpression(Object item, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(item, XPathEvaluationResult.class);
* }</pre>
* <p>
* The parameter {@code item} represents the context the XPath expression
* will be operated on. The type of the context is implementation-dependent.
* If the value is {@code null}, the operation must have no dependency on
* the context, otherwise an XPathExpressionException will be thrown.
*
* @implNote
* The type of the context is usually {@link org.w3c.dom.Node}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* evaluateExpression(item, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param item The context the XPath expression will be evaluated in.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(Object item)
throws XPathExpressionException
{
return evaluateExpression(item, XPathEvaluationResult.class);
}
/**
* Evaluate the compiled XPath expression in the specified context,
* and return the result with the type specified through the {@code class type}
* <p>
* This method builds a data model for the {@link InputSource} and calls
* {@link #evaluateExpression(Object item, Class type)} on the resulting
* document object.
* <P>
* By default, the JDK's data model is {@link org.w3c.dom.Document}.
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
(T)evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type));
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
* XPathEvaluationResult as the type will result in IllegalArgumentException.
* Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
* this method.
*
* @param <T> The class type that will be returned by the XPath expression.
* @param source The {@code InputSource} of the document to evaluate over.
* @param type The class type expected to be returned by the XPath expression.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If {@code type} is not of the types
* corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
* XPathResultType}, or XPathEvaluationResult is specified as the type but an
* implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type
* is not available.
* @throws NullPointerException If {@code source or type} is {@code null}.
*
* @since 1.9
*/
default <T>T evaluateExpression(InputSource source, Class<T> type)
throws XPathExpressionException
{
return type.cast(evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type)));
}
/**
* Evaluate the compiled XPath expression in the specified context. This is
* equivalent to calling {@link #evaluateExpression(InputSource source, Class type)}
* with type {@link XPathEvaluationResult}:
* <pre> {@code
* evaluateExpression(source, XPathEvaluationResult.class);
* }</pre>
* <p>
*
* @implSpec
* The default implementation in the XPath API is equivalent to:
* <pre> {@code
* (XPathEvaluationResult)evaluateExpression(source, XPathEvaluationResult.class);
* }</pre>
*
* Since the {@code evaluate} method does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY}
* type, the default implementation of this method will always throw an
* IllegalArgumentException. Any implementation supporting the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
* override this method.
*
* @param source The {@code InputSource} of the document to evaluate over.
*
* @return The result of evaluating the expression.
*
* @throws XPathExpressionException If the expression cannot be evaluated.
* @throws IllegalArgumentException If the implementation of this method
* does not support the
* {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
* @throws NullPointerException If {@code source} is {@code null}.
*
* @since 1.9
*/
default XPathEvaluationResult<?> evaluateExpression(InputSource source)
throws XPathExpressionException
{
return evaluateExpression(source, XPathEvaluationResult.class);
}
} }

View file

@ -117,7 +117,7 @@ public abstract class XPathFactory {
* and returns it if it is successfully created. * and returns it if it is successfully created.
* </li> * </li>
* <li> * <li>
* ${java.home}/conf/jaxp.properties is read and the value associated with the key being the system property above is looked for. * ${java.home}/lib/jaxp.properties is read and the value associated with the key being the system property above is looked for.
* If present, the value is processed just like above. * If present, the value is processed just like above.
* </li> * </li>
* <li> * <li>

View file

@ -176,9 +176,9 @@ class XPathFactoryFinder {
String javah = ss.getSystemProperty( "java.home" ); String javah = ss.getSystemProperty( "java.home" );
String configFile = javah + File.separator + String configFile = javah + File.separator +
"conf" + File.separator + "jaxp.properties"; "lib" + File.separator + "jaxp.properties";
// try to read from $java.home/conf/jaxp.properties // try to read from $java.home/lib/jaxp.properties
try { try {
if(firstTime){ if(firstTime){
synchronized(cacheProps){ synchronized(cacheProps){
@ -193,7 +193,7 @@ class XPathFactoryFinder {
} }
} }
final String factoryClassName = cacheProps.getProperty(propertyName); final String factoryClassName = cacheProps.getProperty(propertyName);
debugPrintln("found " + factoryClassName + " in $java.home/conf/jaxp.properties"); debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
if (factoryClassName != null) { if (factoryClassName != null) {
xpathFactory = createInstance(factoryClassName, true); xpathFactory = createInstance(factoryClassName, true);

View file

@ -0,0 +1,65 @@
/*
* 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 javax.xml.xpath;
import java.util.Iterator;
import org.w3c.dom.Node;
/**
* XPathNodes represents a set of nodes selected by a location path as specified
* in <a href="http://www.w3.org/TR/xpath/#node-sets">XML Path Language (XPath)
* Version 1.0, 3.3 Node-sets</a>.
*
* @since 1.9
*/
public interface XPathNodes extends Iterable<Node> {
/**
* Returns an iterator of the Nodes.
*
* @return an Iterator.
*/
@Override
public abstract Iterator<Node> iterator();
/**
* Returns the number of items in the result
*
* @return The number of items in the result
*/
public abstract int size();
/**
* Returns a Node at the specified position
*
* @param index Index of the element to return.
* @return The Node at the specified position.
* @throws javax.xml.xpath.XPathException If the index is out of range
* (index &lt; 0 || index &gt;= size())
*/
public abstract Node get(int index)
throws XPathException;
}

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!-- <!--
Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it
@ -23,35 +25,35 @@ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any or visit www.oracle.com if you need additional information or have any
questions. questions.
--> -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>javax.xml.xpath</title>
<meta name="@author" content="mailto:Ben@galbraiths.org" />
<meta name="@author" content="mailto:Norman.Walsh@Sun.com" />
<meta name="@author" content="mailto:Jeff.Suttor@Sun.com" />
<meta name="@see" content="http://www.w3.org/TR/xpath" />
<meta name="@since" content="1.5" />
</head> </head>
<body bgcolor="white">
<body> This package provides an <em>object-model neutral</em> API for the
<p>This package provides an <em>object-model neutral</em> API for the
evaluation of XPath expressions and access to the evaluation evaluation of XPath expressions and access to the evaluation
environment. environment.
</p>
<p>The following XML standards apply:</p> <p>
The XPath API supports <a href="http://www.w3.org/TR/xpath">
<ul> XML Path Language (XPath) Version 1.0</a>
<li><a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
</ul>
<hr /> <hr />
<h2>XPath Overview</h2> <ul>
<li><a href='#XPath.Overview'>1. XPath Overview</a></li>
<li><a href='#XPath.Expressions'>2. XPath Expressions</a></li>
<li><a href='#XPath.Datatypes'>3. XPath Data Types</a>
<ul>
<li><a href='#XPath.Datatypes.QName'>3.1 QName Types</a>
<li><a href='#XPath.Datatypes.Class'>3.2 Class Types</a>
<li><a href='#XPath.Datatypes.Enum'>3.3 Enum Types</a>
</ul>
</li>
<li><a href='#XPath.Context'>4. XPath Context</a></li>
<li><a href='#XPath.Use'>5. Using the XPath API</a></li>
</ul>
<p>
<a name="XPath.Overview"></a>
<h3>1. XPath Overview</h3>
<p>The XPath language provides a simple, concise syntax for selecting <p>The XPath language provides a simple, concise syntax for selecting
nodes from an XML document. XPath also provides rules for converting a nodes from an XML document. XPath also provides rules for converting a
@ -67,7 +69,8 @@ stand-alone language, as a single XPath expression can be used to
replace many lines of DOM API code. replace many lines of DOM API code.
</p> </p>
<h3>XPath Expressions</h3> <a name="XPath.Expressions"></a>
<h3>2. XPath Expressions</h3>
<p>An XPath <em>expression</em> is composed of a <em>location <p>An XPath <em>expression</em> is composed of a <em>location
path</em> and one or more optional <em>predicates</em>. Expressions path</em> and one or more optional <em>predicates</em>. Expressions
@ -76,18 +79,22 @@ may also include XPath variables.
<p>The following is an example of a simple XPath expression:</p> <p>The following is an example of a simple XPath expression:</p>
<blockquote>
<pre> <pre>
/foo/bar /foo/bar
</pre> </pre>
</blockquote>
<p>This example would select the <code>&lt;bar&gt;</code> element in <p>This example would select the <code>&lt;bar&gt;</code> element in
an XML document such as the following:</p> an XML document such as the following:</p>
<blockquote>
<pre> <pre>
&lt;foo&gt; &lt;foo&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;/foo&gt; &lt;/foo&gt;
</pre> </pre>
</blockquote>
<p>The expression <code>/foo/bar</code> is an example of a location <p>The expression <code>/foo/bar</code> is an example of a location
path. While XPath location paths resemble Unix-style file system path. While XPath location paths resemble Unix-style file system
@ -96,30 +103,36 @@ paths, an important distinction is that XPath expressions return
<code>&lt;bar&gt;</code> elements in the following document would be <code>&lt;bar&gt;</code> elements in the following document would be
selected by the <code>/foo/bar</code> expression:</p> selected by the <code>/foo/bar</code> expression:</p>
<blockquote>
<pre> <pre>
&lt;foo&gt; &lt;foo&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;bar/&gt; &lt;bar/&gt;
&lt;/foo&gt; &lt;/foo&gt;
</pre> </pre>
</blockquote>
<p>A special location path operator, <code>//</code>, selects nodes at <p>A special location path operator, <code>//</code>, selects nodes at
any depth in an XML document. The following example selects all any depth in an XML document. The following example selects all
<code>&lt;bar&gt;</code> elements regardless of their location in a <code>&lt;bar&gt;</code> elements regardless of their location in a
document:</p> document:</p>
<blockquote>
<pre> <pre>
//bar //bar
</pre> </pre>
</blockquote>
<p>A wildcard operator, *, causes all element nodes to be selected. <p>A wildcard operator, *, causes all element nodes to be selected.
The following example selects all children elements of a The following example selects all children elements of a
<code>&lt;foo&gt;</code> element:</p> <code>&lt;foo&gt;</code> element:
<blockquote>
<pre> <pre>
/foo/* /foo/*
</pre> </pre>
</blockquote>
<p>In addition to element nodes, XPath location paths may also address <p>In addition to element nodes, XPath location paths may also address
attribute nodes, text nodes, comment nodes, and processing instruction attribute nodes, text nodes, comment nodes, and processing instruction
@ -166,35 +179,27 @@ location path. Predicates are of the form
<code>&lt;foo&gt;</code> elements that contain an <code>include</code> <code>&lt;foo&gt;</code> elements that contain an <code>include</code>
attribute with the value of <code>true</code>:</p> attribute with the value of <code>true</code>:</p>
<blockquote>
<pre> <pre>
//foo[@include='true'] //foo[@include='true']
</pre> </pre>
</blockquote>
<p>Predicates may be appended to each other to further refine an <p>Predicates may be appended to each other to further refine an
expression, such as:</p> expression, such as:</p>
<blockquote>
<pre> <pre>
//foo[@include='true'][@mode='bar'] //foo[@include='true'][@mode='bar']
</pre> </pre>
</blockquote>
<h3>Using the XPath API</h3> <a name="XPath.Datatypes"></a>
<h3>3. XPath Data Types</h3>
<p>
The following example demonstrates using the XPath API to select one
or more nodes from an XML document:</p>
<pre>
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget";
InputSource inputSource = new InputSource("widgets.xml");
NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
</pre>
<h3>XPath Expressions and Types</h3>
<p>While XPath expressions select nodes in the XML document, the XPath <p>While XPath expressions select nodes in the XML document, the XPath
API allows the selected nodes to be coalesced into one of the API allows the selected nodes to be coalesced into one of the
following other data types:</p> following data types:</p>
<ul> <ul>
<li><code>Boolean</code></li> <li><code>Boolean</code></li>
@ -202,14 +207,10 @@ following other data types:</p>
<li><code>String</code></li> <li><code>String</code></li>
</ul> </ul>
<p>The desired return type is specified by a {@link <a name="XPath.Datatypes.QName"></a>
javax.xml.namespace.QName} parameter in method call used to evaluate <h3>3.1 QName types</h3>
the expression, which is either a call to The XPath API defines the following {@link javax.xml.namespace.QName} types to
<code>XPathExpression.evalute(...)</code> or to one of the represent return types of an XPath evaluation:
<code>XPath.evaluate(...)</code> convenience methods. The allowed
QName values are specified as constants in the {@link
javax.xml.xpath.XPathConstants} class; they are:</p>
<ul> <ul>
<li>{@link javax.xml.xpath.XPathConstants#NODESET}</li> <li>{@link javax.xml.xpath.XPathConstants#NODESET}</li>
<li>{@link javax.xml.xpath.XPathConstants#NODE}</li> <li>{@link javax.xml.xpath.XPathConstants#NODE}</li>
@ -218,26 +219,71 @@ javax.xml.xpath.XPathConstants} class; they are:</p>
<li>{@link javax.xml.xpath.XPathConstants#NUMBER}</li> <li>{@link javax.xml.xpath.XPathConstants#NUMBER}</li>
</ul> </ul>
<p>The return type is specified by a {@link javax.xml.namespace.QName} parameter
in method call used to evaluate the expression, which is either a call to
<code>XPathExpression.evalute(...)</code> or <code>XPath.evaluate(...)</code>
methods.
<p>When a <code>Boolean</code> return type is requested, <p>When a <code>Boolean</code> return type is requested,
<code>Boolean.TRUE</code> is returned if one or more nodes were <code>Boolean.TRUE</code> is returned if one or more nodes were
selected; otherwise, <code>Boolean.FALSE</code> is returned.</p> selected; otherwise, <code>Boolean.FALSE</code> is returned.
<p>The <code>String</code> return type is a convenience for retrieving <p>The <code>String</code> return type is a convenience for retrieving
the character data from a text node, attribute node, comment node, or the character data from a text node, attribute node, comment node, or
processing-instruction node. When used on an element node, the value processing-instruction node. When used on an element node, the value
of the child text nodes is returned. of the child text nodes is returned.
</p>
<p>The <code>Number</code> return type attempts to coalesce the text <p>The <code>Number</code> return type attempts to coalesce the text
of a node to a <code>double</code> data type. of a node to a <code>double</code> data type.
</p>
<h3>XPath Context</h3> <a name="XPath.Datatypes.Class"></a>
<h3>3.2 Class types</h3>
In addition to the QName types, the XPath API supports the use of Class types
through the <code>XPathExpression.evaluteExpression(...)</code> or
<code>XPath.evaluateExpression(...)</code> methods.
The XPath data types are mapped to Class types as follows:
<ul>
<li><code>Boolean</code> -- <code>Boolean.class</code></li>
<li><code>Number</code> -- <code>Number.class</code></li>
<li><code>String</code> -- <code>String.class</code></li>
<li><code>Nodeset</code> -- <code>XPathNodes.class</code></li>
<li><code>Node</code> -- <code>Node.class</code></li>
</ul>
<p>
Of the subtypes of Number, only Double, Integer and Long are supported.
<a name="XPath.Datatypes.Enum"></a>
<h3>3.3 Enum types</h3>
Enum types are defined in {@link javax.xml.xpath.XPathEvaluationResult.XPathResultType}
that provide mappings between the QName and Class types above. The result of
evaluating an expression using the <code>XPathExpression.evaluteExpression(...)</code>
or <code>XPath.evaluateExpression(...)</code> methods will be of one of these types.
<a name="XPath.Context"></a>
<h3>4. XPath Context</h3>
<p>XPath location paths may be relative to a particular node in the <p>XPath location paths may be relative to a particular node in the
document, known as the <code>context</code>. Consider the following document, known as the <code>context</code>. A context consists of:
XML document:</p> <ul>
<li>a node (the context node)</li>
<li>a pair of non-zero positive integers (the context position and the context size)</li>
<li>a set of variable bindings</li>
<li>a function library</li>
<li>the set of namespace declarations in scope for the expression</li>
</ul>
<p>
It is an XML document tree represented as a hierarchy of nodes, a
{@link org.w3c.dom.Node} for example, in the JDK implementation.
<a name="XPath.Use"></a>
<h3>5. Using the XPath API</h3>
Consider the following XML document:
<p>
<blockquote>
<pre> <pre>
&lt;widgets&gt; &lt;widgets&gt;
&lt;widget&gt; &lt;widget&gt;
@ -246,36 +292,88 @@ XML document:</p>
&lt;/widget&gt; &lt;/widget&gt;
&lt;/widgets&gt; &lt;/widgets&gt;
</pre> </pre>
</blockquote>
<p>The <code>&lt;widget&gt;</code> element can be selected with the <p>
following XPath API code:</p> The <code>&lt;widget&gt;</code> element can be selected with the following process:
<blockquote>
<pre> <pre>
// parse the XML as a W3C Document // parse the XML as a W3C Document
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new File("/widgets.xml")); Document document = builder.parse(new File("/widgets.xml"));
//Get an XPath object and evaluate the expression
XPath xpath = XPathFactory.newInstance().newXPath(); XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget"; String expression = "/widgets/widget";
Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE); Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
//or using the evaluateExpression method
Node widgetNode = xpath.evaluateExpression(expression, document, Node.class);
</pre> </pre>
</blockquote>
<p>With a reference to the <code>&lt;widget&gt;</code> element, a <p>With a reference to the <code>&lt;widget&gt;</code> element, a
relative XPath expression can now written to select the relative XPath expression can be written to select the
<code>&lt;manufacturer&gt;</code> child element:</p> <code>&lt;manufacturer&gt;</code> child element:</p>
<blockquote>
<pre> <pre>
XPath xpath = XPathFactory.newInstance().newXPath(); XPath xpath = XPathFactory.newInstance().newXPath();
<strong>String expression = "manufacturer";</strong> <strong>String expression = "manufacturer";</strong>
Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE); Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE);
</pre>
<ul> //or using the evaluateExpression method
<li>Author <a href="mailto:Ben@galbraiths.org">Ben Galbraith</a></li> Node manufacturerNode = xpath.evaluateExpression(expression, <strong>widgetNode</strong>, Node.class);
<li>Author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a></li> </pre>
<li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li> </blockquote>
<li>See <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
<li>Since 1.5</li> <p>
</ul> In the above example, the XML file is read into a DOM Document before being passed
to the XPath API. The following code demonstrates the use of InputSource to
leave it to the XPath implementation to process it:
<blockquote>
<pre>
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget";
InputSource inputSource = new InputSource("widgets.xml");
NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
//or using the evaluateExpression method
XPathNodes nodes = xpath.evaluate(expression, inputSource, XPathNodes.class);
</pre>
</blockquote>
<p>
In the above cases, the type of the expected results are known. In case where
the result type is unknown or any type, the {@link javax.xml.xpath.XPathEvaluationResult}
may be used to determine the return type. The following code demonstrates the usage:
<blockquote>
<pre>
XPathEvaluationResult&lt;?&gt; result = xpath.evaluateExpression(expression, document);
switch (result.type()) {
case NODESET:
XPathNodes nodes = (XPathNodes)result.value();
...
break;
}
</pre>
</blockquote>
<p>
The XPath 1.0 Number data type is defined as a double. However, the XPath
specification also provides functions that returns Integer type. To facilitate
such operations, the XPath API allows Integer and Long to be used in
{@code evaluateExpression} method such as the following code:
<p>
<blockquote>
<pre>
int count = xpath.evaluate("count(/widgets/widget)", document, Integer.class);
</pre>
</blockquote>
@since 1.5
</body> </body>
</html> </html>

View file

@ -0,0 +1,297 @@
/*
* Copyright (c) 1999, 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.
*
* 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 javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
/*
* @summary Class containing the test cases for SchemaFactory
*/
@Test(singleThreaded = true)
public class SchemaFactoryTest {
@BeforeClass
public void setup() throws SAXException, IOException, ParserConfigurationException {
sf = newSchemaFactory();
assertNotNull(sf);
xsd1 = Files.readAllBytes(Paths.get(XML_DIR + "test.xsd"));
xsd2 = Files.readAllBytes(Paths.get(XML_DIR + "test1.xsd"));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
xsdDoc1 = db.parse(newInputStream(xsd1));
xsdDoc2 = db.parse(newInputStream(xsd2));
xml = Files.readAllBytes(Paths.get(XML_DIR + "test.xml"));
}
@Test(expectedExceptions = SAXParseException.class)
public void testNewSchemaDefault() throws SAXException, IOException {
validate(sf.newSchema());
}
@Test
public void testNewSchemaWithFile() throws SAXException, IOException {
validate(sf.newSchema(new File(XML_DIR + "test.xsd")));
}
@Test(expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullFile() throws SAXException {
sf.newSchema((File) null);
}
@DataProvider(name = "valid-source")
public Object[][] getValidSource() {
return new Object[][] {
{ streamSource(xsd1) },
{ saxSource(xsd1) },
{ domSource(xsdDoc1) } };
}
@Test(dataProvider = "valid-source")
public void testNewSchemaWithValidSource(Source schema) throws SAXException, IOException {
validate(sf.newSchema(schema));
}
@DataProvider(name = "invalid-source")
public Object[][] getInvalidSource() {
return new Object[][] {
{ nullStreamSource() },
{ nullSaxSource() } };
}
@Test(dataProvider = "invalid-source", expectedExceptions = SAXParseException.class)
public void testNewSchemaWithInvalidSource(Source schema) throws SAXException {
sf.newSchema(schema);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullSource() throws SAXException {
sf.newSchema((Source)null);
}
@DataProvider(name = "valid-sources")
public Object[][] getValidSources() {
return new Object[][] {
{ streamSource(xsd1), streamSource(xsd2) },
{ saxSource(xsd1), saxSource(xsd2) },
{ domSource(xsdDoc1), domSource(xsdDoc2) } };
}
@Test(dataProvider = "valid-sources")
public void testNewSchemaWithValidSourceArray(Source schema1, Source schema2) throws SAXException, IOException {
validate(sf.newSchema(new Source[] { schema1, schema2 }));
}
@DataProvider(name = "invalid-sources")
public Object[][] getInvalidSources() {
return new Object[][] {
{ streamSource(xsd1), nullStreamSource() },
{ nullStreamSource(), nullStreamSource() },
{ saxSource(xsd1), nullSaxSource() },
{ nullSaxSource(), nullSaxSource() } };
}
@Test(dataProvider = "invalid-sources", expectedExceptions = SAXParseException.class)
public void testNewSchemaWithInvalidSourceArray(Source schema1, Source schema2) throws SAXException {
sf.newSchema(new Source[] { schema1, schema2 });
}
@DataProvider(name = "null-sources")
public Object[][] getNullSources() {
return new Object[][] {
{ new Source[] { domSource(xsdDoc1), null } },
{ new Source[] { null, null } },
{ null } };
}
@Test(dataProvider = "null-sources", expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullSourceArray(Source[] schemas) throws SAXException {
sf.newSchema(schemas);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNewSchemaWithNullUrl() throws SAXException {
sf.newSchema((URL) null);
}
@Test
public void testErrorHandler() {
SchemaFactory sf = newSchemaFactory();
assertNull(sf.getErrorHandler(), "When SchemaFactory is created, initially ErrorHandler should not be set.");
ErrorHandler handler = new MyErrorHandler();
sf.setErrorHandler(handler);
assertSame(sf.getErrorHandler(), handler);
sf.setErrorHandler(null);
assertNull(sf.getErrorHandler());
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.getProperty(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.setProperty(UNRECOGNIZED_NAME, "test");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.getProperty(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.setProperty(null, "test");
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.getFeature(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
sf.setFeature(UNRECOGNIZED_NAME, true);
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.getFeature(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
SchemaFactory sf = newSchemaFactory();
assertNotNull(sf);
sf.setFeature(null, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidSchemaLanguage() {
final String INVALID_SCHEMA_LANGUAGE = "http://relaxng.org/ns/structure/1.0";
SchemaFactory.newInstance(INVALID_SCHEMA_LANGUAGE);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullSchemaLanguage() {
SchemaFactory.newInstance(null);
}
private void validate(Schema schema) throws SAXException, IOException {
schema.newValidator().validate(new StreamSource(new ByteArrayInputStream(xml)));
}
private InputStream newInputStream(byte[] xsd) {
return new ByteArrayInputStream(xsd);
}
private Source streamSource(byte[] xsd) {
return new StreamSource(newInputStream(xsd));
}
private Source nullStreamSource() {
return new StreamSource((InputStream) null);
}
private Source saxSource(byte[] xsd) {
return new SAXSource(new InputSource(newInputStream(xsd)));
}
private Source nullSaxSource() {
return new SAXSource(new InputSource((InputStream) null));
}
private Source domSource(Document xsdDoc) {
return new DOMSource(xsdDoc);
}
private SchemaFactory newSchemaFactory() {
return SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
}
private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
private SchemaFactory sf;
private byte[] xsd1;
private byte[] xsd2;
private Document xsdDoc1;
private Document xsdDoc2;
private byte[] xml;
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 1999, 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.
*
* 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 javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.TypeInfoProvider;
import javax.xml.validation.ValidatorHandler;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/*
* @summary test ValidatorHandler.getTypeInfoProvider()
*/
public class TypeInfoProviderTest extends JAXPFileBaseTest {
private ValidatorHandler validatorHandler;
@Test
public void test() throws SAXException, ParserConfigurationException, IOException {
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File(XML_DIR + "shiporder11.xsd"));
validatorHandler = schema.newValidatorHandler();
MyDefaultHandler myDefaultHandler = new MyDefaultHandler();
validatorHandler.setContentHandler(myDefaultHandler);
InputSource is = new InputSource(filenameToURL(XML_DIR + "shiporder11.xml"));
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
XMLReader xmlReader = parserFactory.newSAXParser().getXMLReader();
xmlReader.setContentHandler(validatorHandler);
xmlReader.parse(is);
}
private class MyDefaultHandler extends DefaultHandler {
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
TypeInfoProvider typeInfoProvider = validatorHandler.getTypeInfoProvider();
int index = atts.getIndex("orderid");
if (index != -1) {
System.out.println(" Index " + index);
System.out.println(" ElementType " + typeInfoProvider.getElementTypeInfo().getTypeName());
assertEquals(typeInfoProvider.getAttributeTypeInfo(index).getTypeName(), "string");
assertTrue(typeInfoProvider.isSpecified(index));
assertFalse(typeInfoProvider.isIdAttribute(index));
}
}
}
}

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 1999, 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.
*
* 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 javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import java.io.File;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.ValidatorHandler;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.helpers.DefaultHandler;
/*
* @summary Class containing the test cases for ValidatorHandler API
*/
public class ValidatorHandlerTest {
@BeforeClass
public void setup() throws SAXException {
schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
assertNotNull(schema);
}
@Test
public void testErrorHandler() {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNull(validatorHandler.getErrorHandler(), "When ValidatorHandler is created, initially ErrorHandler should not be set.");
ErrorHandler handler = new MyErrorHandler();
validatorHandler.setErrorHandler(handler);
assertSame(validatorHandler.getErrorHandler(), handler);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
validatorHandler.getProperty(FEATURE_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
validatorHandler.setProperty(FEATURE_NAME, "test");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.getProperty(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.setProperty(null, "test");
}
public void testFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertFalse(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
validatorHandler.setFeature(FEATURE_NAME, true);
assertTrue(validatorHandler.getFeature(FEATURE_NAME), "The feature should be false by default.");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.getFeature(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNotNull(validatorHandler);
validatorHandler.setFeature(null, true);
}
@Test
public void testContentHandler() {
ValidatorHandler validatorHandler = getValidatorHandler();
assertNull(validatorHandler.getContentHandler(), "When ValidatorHandler is created, initially ContentHandler should not be set.");
ContentHandler handler = new DefaultHandler();
validatorHandler.setContentHandler(handler);
assertSame(validatorHandler.getContentHandler(), handler);
validatorHandler.setContentHandler(null);
assertNull(validatorHandler.getContentHandler());
}
private ValidatorHandler getValidatorHandler() {
return schema.newValidatorHandler();
}
private static final String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes";
private Schema schema;
}

View file

@ -0,0 +1,207 @@
/*
* Copyright (c) 1999, 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.
*
* 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 javax.xml.validation.ptests;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.helpers.DefaultHandler;
/*
* @summary Class containing the test cases for Validator API
*/
public class ValidatorTest extends JAXPFileBaseTest {
@BeforeClass
public void setup() throws SAXException, IOException, ParserConfigurationException {
schema = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI).newSchema(new File(XML_DIR + "test.xsd"));
assertNotNull(schema);
xmlFileUri = filenameToURL(XML_DIR + "test.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
xmlDoc = dbf.newDocumentBuilder().parse(xmlFileUri);
}
@Test
public void testValidateStreamSource() throws SAXException, IOException {
Validator validator = getValidator();
validator.setErrorHandler(new MyErrorHandler());
validator.validate(getStreamSource());
}
@Test(expectedExceptions = NullPointerException.class)
public void testValidateNullSource() throws SAXException, IOException {
Validator validator = getValidator();
assertNotNull(validator);
validator.validate(null);
}
@Test
public void testErrorHandler() {
Validator validator = getValidator();
assertNull(validator.getErrorHandler(), "When Validator is created, initially ErrorHandler should not be set.");
ErrorHandler mh = new MyErrorHandler();
validator.setErrorHandler(mh);
assertSame(validator.getErrorHandler(), mh);
}
@DataProvider(name = "source-result")
public Object[][] getSourceAndResult() {
return new Object[][] {
{ getStreamSource(), null },
{ getSAXSource(), getSAXResult() },
{ getDOMSource(), getDOMResult() },
{ getSAXSource(), null },
{ getDOMSource(), null } };
}
@Test(dataProvider = "source-result")
public void testValidateWithResult(Source source, Result result) throws SAXException, IOException {
Validator validator = getValidator();
validator.validate(source, result);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.getProperty(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.setProperty(UNRECOGNIZED_NAME, "test");
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.getProperty(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.setProperty(null, "test");
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.getFeature(UNRECOGNIZED_NAME);
}
@Test(expectedExceptions = SAXNotRecognizedException.class)
public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
validator.setFeature(UNRECOGNIZED_NAME, true);
}
@Test(expectedExceptions = NullPointerException.class)
public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.getFeature(null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
Validator validator = getValidator();
assertNotNull(validator);
validator.setFeature(null, true);
}
private Validator getValidator() {
return schema.newValidator();
}
private Source getStreamSource() {
return new StreamSource(xmlFileUri);
}
private Source getSAXSource() {
return new SAXSource(new InputSource(xmlFileUri));
}
private Result getSAXResult() {
SAXResult saxResult = new SAXResult();
saxResult.setHandler(new DefaultHandler());
return saxResult;
}
private Source getDOMSource() {
return new DOMSource(xmlDoc);
}
private Result getDOMResult() {
return new DOMResult();
}
private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
private String xmlFileUri;
private Schema schema;
private Document xmlDoc;
}

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<contact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
<name> John </name>
<phone>444-121-3434</phone>
</contact>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="contact">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import java.io.StringReader;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.Test;
/*
* @bug 4511326
* @summary In forwards-compatible mode the attribute isn't ignored
*/
public class Bug4511326 extends JAXPBaseTest {
private static final String XSL = "<xsl:stylesheet version='2.0' "
+ "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+ "<xsl:template a='1' match='/'>"
+ "<H2><xsl:value-of select='//author'/></H2>"
+ "<H1><xsl:value-of select='//title'/></H1>"
+ "</xsl:template>"
+ "</xsl:stylesheet>";
@Test
public void ignoreAttTest() throws TransformerConfigurationException {
/* Create a TransformFactory instance */
TransformerFactory transformerFactory = TransformerFactory.newInstance();
/* Create and init a StreamSource instance */
StreamSource source = new StreamSource(new StringReader(XSL));
transformerFactory.newTransformer(source);
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import static javax.xml.transform.OutputKeys.ENCODING;
import static javax.xml.transform.OutputKeys.INDENT;
import static org.testng.Assert.assertEquals;
import java.io.StringReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.Test;
/*
* @bug 4512806
* @summary test transformer.setOutputProperties(null)
*/
public class Bug4512806 extends JAXPBaseTest {
@Test
public void testProperty() throws TransformerConfigurationException {
/* Create a transform factory instance */
TransformerFactory tfactory = TransformerFactory.newInstance();
/* Create a StreamSource instance */
StreamSource streamSource = new StreamSource(new StringReader(xslData));
transformer = tfactory.newTransformer(streamSource);
transformer.setOutputProperty(INDENT, "no");
transformer.setOutputProperty(ENCODING, "UTF-16");
assertEquals(printPropertyValue(INDENT), "indent=no");
assertEquals(printPropertyValue(ENCODING), "encoding=UTF-16");
transformer.setOutputProperties(null);
assertEquals(printPropertyValue(INDENT), "indent=yes");
assertEquals(printPropertyValue(ENCODING), "encoding=UTF-8");
}
private String printPropertyValue(String name) {
return name + "=" + transformer.getOutputProperty(name);
}
private Transformer transformer;
private static final String xslData = "<?xml version='1.0'?>"
+ "<xsl:stylesheet"
+ " version='1.0'"
+ " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
+ ">\n"
+ " <xsl:output method='xml' indent='yes'"
+ " encoding='UTF-8'/>\n"
+ " <xsl:template match='/'>\n"
+ " Hello World! \n"
+ " </xsl:template>\n"
+ "</xsl:stylesheet>";
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.Test;
/*
* @bug 4515047
* @summary test transform an empty dom source
*/
public class Bug4515047 extends JAXPBaseTest {
@Test
public void testCreateTxDoc() throws TransformerException, ParserConfigurationException {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(System.out);
DOMSource source = new DOMSource();
/* This should not throw an Illegal Argument Exception */
//Test empty DOMSource
transformer.transform(source, result);
//Test DOMSource having only an empty node
source.setNode(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
transformer.transform(source, result);
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import jaxp.library.JAXPBaseTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;
/*
* @bug 4515660
* @summary verify property org.xml.sax.driver is used by SAXTransformerFactory
*/
@Test(singleThreaded = true)
public class Bug4515660 extends JAXPBaseTest {
@BeforeClass
public void setSaxDrier() {
setSystemProperty("org.xml.sax.driver", ReaderStub.class.getName());
}
@AfterClass
public void clearSaxDrier() {
setSystemProperty("org.xml.sax.driver", null);
}
@Test
public void testTransformer() throws TransformerException {
String xml = "<?xml version='1.0'?><root/>";
ReaderStub.used = false;
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
InputSource in = new InputSource(new StringReader(xml));
SAXSource source = new SAXSource(in);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
assertTrue(ReaderStub.used);
}
@Test
public void testSAXTransformerFactory() throws TransformerConfigurationException {
final String xsl = "<?xml version='1.0'?>\n" + "<xsl:stylesheet" + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" + " version='1.0'>\n"
+ " <xsl:template match='/'>Hello World!</xsl:template>\n" + "</xsl:stylesheet>\n";
ReaderStub.used = false;
TransformerFactory transFactory = TransformerFactory.newInstance();
assertTrue(transFactory.getFeature(SAXTransformerFactory.FEATURE));
InputSource in = new InputSource(new StringReader(xsl));
SAXSource source = new SAXSource(in);
transFactory.newTransformer(source);
assertTrue(ReaderStub.used);
}
public static class ReaderStub extends XMLFilterImpl {
static boolean used = false;
public ReaderStub() throws ParserConfigurationException, SAXException {
super();
super.setParent(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
used = true;
}
public void parse(InputSource input) throws SAXException, IOException {
used = true;
super.parse(input);
}
public void parse(String systemId) throws SAXException, IOException {
used = true;
super.parse(systemId);
}
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static jaxp.library.JAXPTestUtilities.USER_DIR;
import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold;
import static org.testng.Assert.assertTrue;
import static test.gaptest.GapTestConst.GOLDEN_DIR;
import static test.gaptest.GapTestConst.XML_DIR;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;
/*
* @bug 4693341
* @summary test transforming to stream with external dtd
*/
public class Bug4693341 extends JAXPFileBaseTest {
@Test
public void test() throws TransformerException, ParserConfigurationException, SAXException, IOException {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
String out = USER_DIR + File.separator + "Bug4693341.out";
StreamResult result = new StreamResult(new File(out));
String in = XML_DIR + "Bug4693341.xml";
String golden = GOLDEN_DIR + "Bug4693341.xml";
File file = new File(in);
StreamSource source = new StreamSource(file);
System.out.println(source.getSystemId());
Files.copy(Paths.get(XML_DIR + "Bug4693341.dtd"),
Paths.get(USER_DIR + File.separator + "Bug4693341.dtd"), REPLACE_EXISTING);
transformer.transform(source, result);
assertTrue(compareDocumentWithGold(golden, out));
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static test.gaptest.GapTestConst.XML_DIR;
import java.io.IOException;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
/*
* @bug 4848653
* @summary Verify JAXP schemaLanguage property is ignored if setValidating(false)
*/
public class Bug4848653 extends JAXPFileBaseTest {
@Test
public void test() throws IOException, SAXException, ParserConfigurationException {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", XMLConstants.W3C_XML_SCHEMA_NS_URI);
String filename = XML_DIR + "Bug4848653.xml";
InputSource is = new InputSource(filenameToURL(filename));
XMLReader xmlReader = parser.getXMLReader();
xmlReader.setErrorHandler(new MyErrorHandler());
xmlReader.parse(is);
}
class MyErrorHandler implements ErrorHandler {
public void error(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void warning(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void fatalError(SAXParseException exception) throws SAXParseException {
throw exception;
}
}
}

View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 2003, 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.
*
* 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 test.gaptest;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.testng.Assert.assertEquals;
import static test.gaptest.GapTestConst.GOLDEN_DIR;
import static test.gaptest.GapTestConst.XML_DIR;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPFileBaseTest;
import org.testng.annotations.Test;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
* @bug 4858685 4894410
* @summary test transforming text node
*/
public class Bug4858685 extends JAXPFileBaseTest {
@Test
public void test() throws TransformerException, IOException {
String uri = XML_DIR + "certificate.xml";
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// use URI as a StreamSource
StreamSource streamSource = new StreamSource(filenameToURL(uri));
DOMResult domResult = new DOMResult();
// StreamSource -> DOMResult
transformer.transform(streamSource, domResult);
// dump DOM in a human readable form
String gotString = DOMDump.dumpDom(domResult.getNode());
String goldenString = new String(Files.readAllBytes(Paths.get(GOLDEN_DIR + "Bug4858685.txt")));
assertEquals(gotString, goldenString);
}
/**
* DOMDump: dump a DOM to a String in human readable form. method dumpDOM()
* is static for easy calling:
*/
private static class DOMDump {
/**
* the maximum level to indent with blanks
*/
private static final int BLANKS_LEN = 64;
/**
* each level of the tree will be indented with blanks for readability
*/
private static final String BLANKS = " ";
/**
* dumpDOM will dump the DOM into a String for human readability
*
* @param domNode
* the DOM Node to dump
* @return human readabile DOM as a String
*/
public static String dumpDom(Node domNode) {
return dumpInternal(domNode, 0);
}
/**
* dumpInternal is used internaly to recursively dump DOM Nodes
*
* @param domNode
* to dump
* @param indent
* level
* @return domNode as human readable String
*/
private static String dumpInternal(Node domNode, int indent) {
String result = "";
// indent for readability
result += indentBlanks(indent);
indent += 2;
// protect against null
if (domNode == null) {
result = result + "[null]" + "\n";
return result;
}
// what to output depends on NodeType
short type = domNode.getNodeType();
switch (type) {
case Node.ATTRIBUTE_NODE: {
result += "[attribute] " + domNode.getNodeName() + "=\"" + domNode.getNodeValue() + "\"";
break;
}
case Node.CDATA_SECTION_NODE: {
result += "[cdata] " + domNode.getNodeValue();
break;
}
case Node.COMMENT_NODE: {
result += "[comment] " + domNode.getNodeValue();
break;
}
case Node.DOCUMENT_FRAGMENT_NODE: {
result += "[document fragment]";
break;
}
case Node.DOCUMENT_NODE: {
result += "[document]";
break;
}
case Node.DOCUMENT_TYPE_NODE: {
result += "[document type] " + domNode.getNodeName();
break;
}
case Node.ELEMENT_NODE: {
result += "[element] " + domNode.getNodeName();
// output all attributes for Element
if (domNode.hasAttributes()) {
NamedNodeMap attributes = domNode.getAttributes();
for (int onAttribute = 0; onAttribute < attributes.getLength(); onAttribute++) {
// seprate each attribute with a space
result += " ";
Node attribute = attributes.item(onAttribute);
String namespaceURI = attribute.getNamespaceURI();
String prefix = attribute.getPrefix();
String localName = attribute.getLocalName();
String name = attribute.getNodeName();
String value = attribute.getNodeValue();
// using Namespaces?
if (namespaceURI != null) {
result += "{" + namespaceURI + "}";
}
if (prefix != null) {
result += prefix + ":";
}
// name="value"
result += attribute.getNodeName() + "=\"" + attribute.getNodeValue() + "\"";
}
}
break;
}
case Node.ENTITY_NODE: {
result += "[entity] " + domNode.getNodeName();
break;
}
case Node.ENTITY_REFERENCE_NODE: {
result += "[entity reference] " + domNode.getNodeName();
break;
}
case Node.NOTATION_NODE: {
result += "[notation] " + domNode.getNodeName();
break;
}
case Node.PROCESSING_INSTRUCTION_NODE: {
result += "[pi] target=\"" + domNode.getNodeName() + "\" content=\"" + domNode.getNodeValue() + "\"";
break;
}
case Node.TEXT_NODE: {
result += "[text] " + domNode.getNodeValue();
break;
}
default: {
result += "[unknown]";
break;
}
}
// humans read in lines
result += "\n";
// process children
NodeList children = domNode.getChildNodes();
for (int onChild = 0; onChild < children.getLength(); onChild++) {
Node child = children.item(onChild);
result += dumpInternal(child, indent);
}
// return human readable DOM as String
return result;
}
/**
* indentBlanks will return a String of indent blanks
*
* @param indent
* level
* @return String of blanks
*/
private static String indentBlanks(int indent) {
if (indent == 0) {
return "";
}
if (indent > BLANKS_LEN) {
return BLANKS;
}
return BLANKS.substring(0, indent + 1);
}
}
}

View file

@ -0,0 +1,39 @@
<!ELEMENT SupplierOrder (OrderId, OrderDate, ShippingAddress, LineItems)>
<!ELEMENT OrderId (#PCDATA)>
<!ELEMENT OrderDate (#PCDATA)>
<!ELEMENT ShippingAddress (FirstName, LastName, Street, City, State, Country, ZipCode, Email, Phone)>
<!ELEMENT FirstName (#PCDATA)>
<!ELEMENT LastName (#PCDATA)>
<!ELEMENT Street (#PCDATA)>
<!ELEMENT City (#PCDATA)>
<!ELEMENT State (#PCDATA)>
<!ELEMENT Country (#PCDATA)>
<!ELEMENT ZipCode (#PCDATA)>
<!ELEMENT Email (#PCDATA)>
<!ELEMENT Phone (#PCDATA)>
<!ELEMENT LineItems (LineItem+)>
<!ELEMENT LineItem EMPTY>
<!ATTLIST LineItem
categoryId CDATA #REQUIRED
productId CDATA #REQUIRED
itemId CDATA #REQUIRED
lineNo CDATA #REQUIRED
quantity CDATA #REQUIRED
unitPrice CDATA #REQUIRED
>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SupplierOrder SYSTEM "Bug4693341.dtd" >
<SupplierOrder>
<OrderId>10016</OrderId>
<OrderDate>Wed May 29 12:45:00 PDT 2002</OrderDate>
<ShippingAddress>
<FirstName>ABC</FirstName>
<LastName>XYZ</LastName>
<Street>1234 Anywhere Street</Street>
<City>Palo Alto</City>
<State>California</State>
<Country>USA</Country>
<ZipCode>94303</ZipCode>
<Email>NULL</Email>
<Phone>NULL</Phone>
</ShippingAddress>
<LineItems>
<LineItem categoryId="BIRDS" itemId="EST-18" lineNo="0" productId="AV-CB-01" quantity="1" unitPrice="193.5"/>
</LineItems>
</SupplierOrder>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http://headertest.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<ds:X509Certificate xmlns="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
MIIDVjCCAxICBD6kKrMwCwYHKoZIzjgEAwUAMIGPMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
FDASBgNVBAcTC1NhbnRhIENsYXJhMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMR4w
HAYDVQQLExVKYXZhIGFuZCBYTUwgU29mdHdhcmUxHDAaBgNVBAMTE0pXUy1TZWN1cml0eSBDbGll
bnQwHhcNMDMwNDIxMTczMDI3WhcNMDMwNzIwMTczMDI3WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywg
SW5jLjEeMBwGA1UECxMVSmF2YSBhbmQgWE1MIFNvZnR3YXJlMRwwGgYDVQQDExNKV1MtU2VjdXJp
dHkgQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAV3R+bUfh+u0yaPBV75umKvFB
ucv37ETDak889b7k72kZdGoHz3oDmp69tiNDg5r7IvKtjHGbZ6C3Nv0ycNR7Sed1QPOF4nn/tgUl
j+BvtVW3iiIRgBJ82KP+28QtwPkkxSp7n5HG0v7bE29E/juLduuhKBQTaaCvajuCFxiBrmAwCwYH
KoZIzjgEAwUAAzEAMC4CFQCCuDNmMKjgY6MV1SmAcCdnhuT6VwIVAJBOiPDnDWp2WlKAERF6nOAf
vKz9
</ds:X509Certificate>
</env:Body>
</env:Envelope>

View file

@ -0,0 +1,39 @@
<!ELEMENT SupplierOrder (OrderId, OrderDate, ShippingAddress, LineItems)>
<!ELEMENT OrderId (#PCDATA)>
<!ELEMENT OrderDate (#PCDATA)>
<!ELEMENT ShippingAddress (FirstName, LastName, Street, City, State, Country, ZipCode, Email, Phone)>
<!ELEMENT FirstName (#PCDATA)>
<!ELEMENT LastName (#PCDATA)>
<!ELEMENT Street (#PCDATA)>
<!ELEMENT City (#PCDATA)>
<!ELEMENT State (#PCDATA)>
<!ELEMENT Country (#PCDATA)>
<!ELEMENT ZipCode (#PCDATA)>
<!ELEMENT Email (#PCDATA)>
<!ELEMENT Phone (#PCDATA)>
<!ELEMENT LineItems (LineItem+)>
<!ELEMENT LineItem EMPTY>
<!ATTLIST LineItem
categoryId CDATA #REQUIRED
productId CDATA #REQUIRED
itemId CDATA #REQUIRED
lineNo CDATA #REQUIRED
quantity CDATA #REQUIRED
unitPrice CDATA #REQUIRED
>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SupplierOrder SYSTEM "Bug4693341.dtd" >
<SupplierOrder>
<OrderId>10016</OrderId>
<OrderDate>Wed May 29 12:45:00 PDT 2002</OrderDate>
<ShippingAddress>
<FirstName>ABC</FirstName>
<LastName>XYZ</LastName>
<Street>1234 Anywhere Street</Street>
<City>Palo Alto</City>
<State>California</State>
<Country>USA</Country>
<ZipCode>94303</ZipCode>
<Email>NULL</Email>
<Phone>NULL</Phone>
</ShippingAddress>
<LineItems>
<LineItem categoryId="BIRDS" itemId="EST-18" lineNo="0" productId="AV-CB-01" quantity="1" unitPrice="193.5"/>
</LineItems>
</SupplierOrder>

View file

@ -0,0 +1,30 @@
[document]
[element] env:Envelope {http://www.w3.org/2000/xmlns/}xmlns:xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:ns0="http://headertest.org/" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:xsd="http://www.w3.org/2001/XMLSchema" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
[text]
[element] env:Body
[text]
[element] ds:X509Certificate xmlns="" {http://www.w3.org/2000/xmlns/}xmlns:xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
[text]
MIIDVjCCAxICBD6kKrMwCwYHKoZIzjgEAwUAMIGPMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
FDASBgNVBAcTC1NhbnRhIENsYXJhMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMR4w
HAYDVQQLExVKYXZhIGFuZCBYTUwgU29mdHdhcmUxHDAaBgNVBAMTE0pXUy1TZWN1cml0eSBDbGll
bnQwHhcNMDMwNDIxMTczMDI3WhcNMDMwNzIwMTczMDI3WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywg
SW5jLjEeMBwGA1UECxMVSmF2YSBhbmQgWE1MIFNvZnR3YXJlMRwwGgYDVQQDExNKV1MtU2VjdXJp
dHkgQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAV3R+bUfh+u0yaPBV75umKvFB
ucv37ETDak889b7k72kZdGoHz3oDmp69tiNDg5r7IvKtjHGbZ6C3Nv0ycNR7Sed1QPOF4nn/tgUl
j+BvtVW3iiIRgBJ82KP+28QtwPkkxSp7n5HG0v7bE29E/juLduuhKBQTaaCvajuCFxiBrmAwCwYH
KoZIzjgEAwUAAzEAMC4CFQCCuDNmMKjgY6MV1SmAcCdnhuT6VwIVAJBOiPDnDWp2WlKAERF6nOAf
vKz9
[text]
[text]

View file

@ -0,0 +1,40 @@
/*
* 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.
*
* 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 javax.xml.validation.ptests;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
class MyErrorHandler implements ErrorHandler {
public void error(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void warning(SAXParseException exception) throws SAXParseException {
throw exception;
}
public void fatalError(SAXParseException exception) throws SAXParseException {
throw exception;
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.
*
* 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 javax.xml.validation.ptests;
import static jaxp.library.JAXPTestUtilities.FILE_SEP;
import static jaxp.library.JAXPTestUtilities.getPathByClassName;
/**
* This class defines the path constant
*/
public class ValidationTestConst {
/**
* XML source file directory.
*/
public static final String XML_DIR = getPathByClassName(ValidationTestConst.class,
".." + FILE_SEP + "xmlfiles");
/**
* Golden validation files directory.
*/
public static final String GOLDEN_DIR = getPathByClassName(ValidationTestConst.class,
".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out");
}

View file

@ -0,0 +1,41 @@
/*
* 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.
*
* 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 test.gaptest;
import static jaxp.library.JAXPTestUtilities.FILE_SEP;
import static jaxp.library.JAXPTestUtilities.getPathByClassName;
/**
* This class defines the path constant
*/
public class GapTestConst {
/**
* XML source file directory.
*/
public static final String XML_DIR = getPathByClassName(GapTestConst.class, "xmlfiles");
/**
* Golden validation files directory.
*/
public static final String GOLDEN_DIR = getPathByClassName(GapTestConst.class, "xmlfiles" + FILE_SEP + "out");
}

View file

@ -0,0 +1,190 @@
/*
* 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.
*
* 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 javax.xml.xpath;
import java.io.File;
import javax.xml.xpath.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* @bug 8054196
* @summary Test for the project XPath: support any type. This test covers the new
* evaluateExpression methods of XPath, as well as XPathNodes and XPathEvaluationResult.
*/
public class XPathAnyTypeTest extends XPathTestBase {
/*
Test for resolveFunction(QName functionName,int arity); evaluate throws
NPE if functionName is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void testCheckXPathFunctionResolver02(XPath xpath) throws XPathExpressionException {
xpath.setXPathFunctionResolver((functionName, arity) -> null);
assertEquals(xpath.evaluate(null, "5"), "2");
}
/*
Check that NPE is thrown when expression is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void test01(XPath xpath) throws XPathExpressionException {
double result = xpath.evaluateExpression(null, (Object) null, Double.class);
}
/*
Check that NPE is thrown when the class type is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void test02(XPath xpath) throws XPathExpressionException {
double result = xpath.evaluateExpression("1+1", (Object) null, null);
}
/*
Parameter item can be null when the expression does not depends on the
context.
*/
@Test(dataProvider = "xpath")
public void test03(XPath xpath) throws XPathExpressionException {
int result = xpath.evaluateExpression("1+1", (Object) null, Integer.class);
assertTrue(result == 2);
}
/*
* Test return type: boolean.
*/
@Test(dataProvider = "document")
public void test04(XPath xpath, Document doc) throws XPathExpressionException {
boolean result1 = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc, Boolean.class);
assertTrue(result1);
}
/*
* Test return type: numeric. Subtypes supported: Double, Integer and Long
*/
@Test(dataProvider = "document")
public void test05(XPath xpath, Document doc) throws XPathExpressionException {
double result1 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Double.class);
assertTrue(result1 == 3.0);
int result2 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Integer.class);
assertTrue(result2 == 3);
long result3 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Long.class);
assertTrue(result3 == 3);
}
/*
* Test return type: numeric. Of the subtypes of Number, only Double,
* Integer and Long are required.
*/
@Test(dataProvider = "invalidNumericTypes", expectedExceptions = IllegalArgumentException.class)
public void test06(XPath xpath, Class<Number> type) throws XPathExpressionException {
xpath.evaluateExpression("1+1", (Object) null, type);
}
/*
* Test return type: String.
*/
@Test(dataProvider = "document")
public void test07(XPath xpath, Document doc) throws XPathExpressionException {
String result1 = xpath.evaluateExpression("string(/Customers/Customer[@id=3]/Phone/text())", doc, String.class);
assertTrue(result1.equals("3333333333"));
}
/*
* Test return type: NodeSet.
*/
@Test(dataProvider = "document")
public void test08(XPath xpath, Document doc) throws XPathExpressionException {
XPathNodes nodes = xpath.evaluateExpression("/Customers/Customer", doc, XPathNodes.class);
assertTrue(nodes.size() == 3);
for (Node n : nodes) {
assertEquals(n.getLocalName(), "Customer");
}
}
/*
* Test return type: Node.
*/
@Test(dataProvider = "document")
public void test09(XPath xpath, Document doc) throws XPathExpressionException {
Node n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, Node.class);
assertEquals(n.getLocalName(), "Customer");
}
/*
* Test return type: Unsupported type.
*/
@Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
public void test10(XPath xpath, Document doc) throws XPathExpressionException {
File n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, File.class);
}
/*
* Test return type: Any::Boolean.
*/
@Test(dataProvider = "document")
public void test11(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc);
verifyResult(result, true);
}
/*
* Test return type: Any::Number.
*/
@Test(dataProvider = "document")
public void test12(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("count(/Customers/Customer)", doc);
verifyResult(result, 3.0);
}
/*
* Test return type: Any::String.
*/
@Test(dataProvider = "document")
public void test13(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression(
"string(/Customers/Customer[@id=3]/Phone/text())", doc, XPathEvaluationResult.class);
verifyResult(result, "3333333333");
}
/*
* Test return type: Any::Nodeset.
*/
@Test(dataProvider = "document")
public void test14(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer", doc);
verifyResult(result, "Customer");
}
/*
* Test return type: Any::Node.
*/
@Test(dataProvider = "document")
public void test15(XPath xpath, Document doc) throws XPathExpressionException {
XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc);
verifyResult(result, "Customer");
}
}

View file

@ -0,0 +1,176 @@
/*
* 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.
*
* 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 javax.xml.xpath;
import java.io.File;
import javax.xml.xpath.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* @bug 8054196
* @summary Test for the project XPath: support any type. This test covers the new
* evaluateExpression methods of XPathExpression.
*/
public class XPathExpAnyTypeTest extends XPathTestBase {
/*
* Check that NPE is thrown when the class type is null.
*/
@Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
public void test02(XPath xpath) throws XPathExpressionException {
XPathExpression exp = xpath.compile("1+1");
double result = exp.evaluateExpression((Object)null, null);
}
/*
* Parameter item can be null when the expression does not depends on the
* context.
*/
@Test(dataProvider = "xpath")
public void test03(XPath xpath) throws XPathExpressionException {
XPathExpression exp = xpath.compile("1+1");
int result = exp.evaluateExpression((Object)null, Integer.class);
assertTrue(result == 2);
}
/*
* Test return type: boolean.
*/
@Test(dataProvider = "document")
public void test04(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
boolean result1 = exp.evaluateExpression(doc, Boolean.class);
assertTrue(result1);
}
/*
* Test return type: numeric.
*/
@Test(dataProvider = "document")
public void test05(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("count(/Customers/Customer)");
double result1 = exp.evaluateExpression(doc, Double.class);
assertTrue(result1 == 3.0);
int result2 = exp.evaluateExpression(doc, Integer.class);
assertTrue(result2 == 3);
}
/*
* Test return type: String.
*/
@Test(dataProvider = "document")
public void test06(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
String result1 = exp.evaluateExpression(doc, String.class);
assertTrue(result1.equals("3333333333"));
}
/*
* Test return type: NodeSet.
*/
@Test(dataProvider = "document")
public void test07(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer");
XPathNodes nodes = exp.evaluateExpression(doc, XPathNodes.class);
assertTrue(nodes.size() == 3);
for (Node n : nodes) {
assertEquals(n.getLocalName(), "Customer");
}
}
/*
* Test return type: Node.
*/
@Test(dataProvider = "document")
public void test08(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
Node n = exp.evaluateExpression(doc, Node.class);
assertEquals(n.getLocalName(), "Customer");
}
/*
* Test return type: Unsupported type.
*/
@Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
public void test09(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
File n = exp.evaluateExpression(doc, File.class);
}
/*
* Test return type: Any::Boolean.
*/
@Test(dataProvider = "document")
public void test10(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, true);
}
/*
* Test return type: Any::Number.
*/
@Test(dataProvider = "document")
public void test11(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("count(/Customers/Customer)");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, 3.0);
}
/*
* Test return type: Any::String.
*/
@Test(dataProvider = "document")
public void test12(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc, XPathEvaluationResult.class);
verifyResult(result, "3333333333");
}
/*
* Test return type: Any::Nodeset.
*/
@Test(dataProvider = "document")
public void test13(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, "Customer");
}
/*
* Test return type: Any::Node.
*/
@Test(dataProvider = "document")
public void test14(XPath xpath, Document doc) throws XPathExpressionException {
XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
verifyResult(result, "Customer");
}
}

View file

@ -0,0 +1,140 @@
/*
* 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.
*
* 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 javax.xml.xpath;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.xml.parsers.DocumentBuilderFactory;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.DataProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* Base class for XPath test
*/
class XPathTestBase {
static final String rawXML
= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<Customers>"
+ " <Customer id=\"1\">"
+ " <Name>name1</Name>"
+ " <Phone>1111111111</Phone>"
+ " <Email>123@xyz.com</Email>"
+ " <Address>"
+ " <Street>1111 111st ave</Street>"
+ " <City>The City</City>"
+ " <State>The State</State>"
+ " </Address>"
+ " </Customer>"
+ " <Customer id=\"2\">"
+ " <Name>name1</Name>"
+ " <Phone>2222222222</Phone>"
+ " <Email>123@xyz.com</Email>"
+ " <Address>"
+ " <Street>2222 222nd ave</Street>"
+ " <City>The City</City>"
+ " <State>The State</State>"
+ " </Address>"
+ " </Customer>"
+ " <Customer id=\"3\">"
+ " <Name>name1</Name>"
+ " <Phone>3333333333</Phone>"
+ " <Email>123@xyz.com</Email>"
+ " <Address>"
+ " <Street>3333 333rd ave</Street>"
+ " <City>The City</City>"
+ " <State>The State</State>"
+ " </Address>"
+ " </Customer>"
+ "</Customers>";
void verifyResult(XPathEvaluationResult<?> result, Object expected) {
switch (result.type()) {
case BOOLEAN:
assertTrue(((Boolean) result.value()).equals(expected));
return;
case NUMBER:
assertTrue(((Double) result.value()).equals(expected));
return;
case STRING:
assertTrue(((String) result.value()).equals(expected));
return;
case NODESET:
XPathNodes nodes = (XPathNodes) result.value();
for (Node n : nodes) {
assertEquals(n.getLocalName(), expected);
}
return;
case NODE:
assertTrue(((Node) result.value()).getLocalName().equals(expected));
return;
}
assertFalse(true, "Unsupported type");
}
/*
* DataProvider: XPath object
*/
@DataProvider(name = "xpath")
Object[][] getXPath() {
return new Object[][]{{XPathFactory.newInstance().newXPath()}};
}
/*
* DataProvider: Numeric types not supported
*/
@DataProvider(name = "invalidNumericTypes")
Object[][] getInvalidNumericTypes() {
XPath xpath = XPathFactory.newInstance().newXPath();
return new Object[][]{{xpath, AtomicInteger.class},
{xpath, AtomicInteger.class},
{xpath, AtomicLong.class},
{xpath, BigDecimal.class},
{xpath, BigInteger.class},
{xpath, Byte.class},
{xpath, Float.class},
{xpath, Short.class}
};
}
/*
* DataProvider: XPath and Document objects
*/
@DataProvider(name = "document")
Object[][] getDocument() throws Exception {
DocumentBuilderFactory dBF = DocumentBuilderFactory.newInstance();
dBF.setValidating(false);
dBF.setNamespaceAware(true);
Document doc = dBF.newDocumentBuilder().parse(
new ByteArrayInputStream(rawXML.getBytes("UTF-8")));
return new Object[][]{{XPathFactory.newInstance().newXPath(), doc}};
}
}

View file

@ -293,3 +293,4 @@ edc13d27dc871be57d7ca77eef77e6d04972fee2 jdk9-b43
e529374fbe526dbd668e5e98fc047b42b3bc6d33 jdk9-b45 e529374fbe526dbd668e5e98fc047b42b3bc6d33 jdk9-b45
64ca52b0bda8028636e4ccafbe1107befcdda47d jdk9-b46 64ca52b0bda8028636e4ccafbe1107befcdda47d jdk9-b46
6c17d648d03e4bf4729c3645f8db55d34115e0b7 jdk9-b47 6c17d648d03e4bf4729c3645f8db55d34115e0b7 jdk9-b47
33e7e699804892c0496adf60ad67cc12855aeb61 jdk9-b48

View file

@ -135,7 +135,7 @@ public class SchemaGenerator extends AbstractProcessor {
private void filterClass(List<Reference> classes, Collection<? extends Element> elements) { private void filterClass(List<Reference> classes, Collection<? extends Element> elements) {
for (Element element : elements) { for (Element element : elements) {
if (element.getKind().equals(ElementKind.CLASS)) { if (element.getKind().equals(ElementKind.CLASS) || element.getKind().equals(ElementKind.ENUM)) {
classes.add(new Reference((TypeElement) element, processingEnv)); classes.add(new Reference((TypeElement) element, processingEnv));
filterClass(classes, ElementFilter.typesIn(element.getEnclosedElements())); filterClass(classes, ElementFilter.typesIn(element.getEnclosedElements()));
} }

View file

@ -290,3 +290,4 @@ e336cbd8b15e959e70ed02f0f5e93fa76ebd4c07 jdk9-b41
9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45 9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45
efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46 efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46
b641c14730ac05d9ec8b4f66e6fca3dc21adb403 jdk9-b47 b641c14730ac05d9ec8b4f66e6fca3dc21adb403 jdk9-b47
ebb2eb7f1aec78eb6d8cc4c96f018afa11093cde jdk9-b48

View file

@ -34,28 +34,23 @@ include JavaCompilation.gmk
include NativeCompilation.gmk include NativeCompilation.gmk
include SetupJavaCompilers.gmk include SetupJavaCompilers.gmk
# The exception handling of swing beaninfo which have the own tool directory ################################################################################
ifeq (, $(BUILD_TOOLS_JDK))
$(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
SETUP := GENERATE_OLDBYTECODE, \
ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
SRC := $(JDK_TOPDIR)/make/src/classes, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
COPY := boot.modules ext.modules))
endif
$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/%.template: \ $(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
$(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/%.template SETUP := GENERATE_OLDBYTECODE, \
$(call install-file) ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
SRC := $(JDK_TOPDIR)/make/src/classes, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
COPY := boot.modules ext.modules))
BUILD_TOOLS_JDK += $(foreach i, $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template), $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/$(notdir $i)) $(eval $(call SetupCopyFiles,COPY_NIMBUS_TEMPLATES, \
SRC := $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus, \
DEST := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources, \
FILES := $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template)))
# Resource used by CheckDeps tool BUILD_TOOLS_JDK += $(COPY_NIMBUS_TEMPLATES)
$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed: \
$(JDK_TOPDIR)/make/data/checkdeps/refs.allowed
$(call install-file)
BUILD_TOOLS_JDK += $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed ################################################################################
# Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists. # Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists.
TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
@ -130,10 +125,6 @@ TOOL_OSX_TOBIN = $(JAVA_SMALL) -Djava.awt.headless=true -cp $(BUILDTOOLS_OUTPUTD
TOOL_CLDRCONVERTER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ TOOL_CLDRCONVERTER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
build.tools.cldrconverter.CLDRConverter build.tools.cldrconverter.CLDRConverter
TOOL_CHECKDEPS = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
-cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
build.tools.deps.CheckDeps
TOOL_GENMODULESXML = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \ TOOL_GENMODULESXML = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
-cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \ -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
build.tools.module.GenJdepsModulesXml build.tools.module.GenJdepsModulesXml
@ -161,25 +152,25 @@ $(eval $(call SetupJavaCompilation,BUILD_INTERIM_JIMAGE, \
# Tools needed on solaris because OBJCOPY is broken. # Tools needed on solaris because OBJCOPY is broken.
ifeq ($(OPENJDK_TARGET_OS), solaris) ifeq ($(OPENJDK_TARGET_OS), solaris)
$(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \ $(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \
SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \ SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \
LANG := C, \ LANG := C, \
CC := $(BUILD_CC), \ CC := $(BUILD_CC), \
LDEXE := $(BUILD_LD), \ LDEXE := $(BUILD_LD), \
LDFLAGS := -lelf, \ LDFLAGS := -lelf, \
OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \ OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \
OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
PROGRAM := add_gnu_debuglink)) PROGRAM := add_gnu_debuglink))
$(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \ $(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \
SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \ SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \
LANG := C, \ LANG := C, \
CC := $(BUILD_CC), \ CC := $(BUILD_CC), \
LDEXE := $(BUILD_LD), \ LDEXE := $(BUILD_LD), \
LDFLAGS := -lelf, \ LDFLAGS := -lelf, \
OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \ OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
PROGRAM := fix_empty_sec_hdr_flags)) PROGRAM := fix_empty_sec_hdr_flags))
endif endif
$(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE) $(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE)

View file

@ -1,34 +0,0 @@
#
# This properties-formatted file contains the names of the non-existent types
# that are allowed to be referenced from classes in a profiles image.
#
# The property key is a type that does not exist. The property value is one or
# more types that reference the missing type. The property value also encodes
# the names of the profiles where this reference is allowed.
# jsse.jar is not subsetted by the profiles build. For compact1 and compact2
# then this means that there are references to Kerberos types that do not
# exist. These references are harmless.
#
javax.security.auth.kerberos.KerberosKey=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
javax.security.auth.kerberos.KerberosPrincipal=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
javax.security.auth.kerberos.KerberosTicket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
javax.security.auth.kerberos.KeyTab=sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
javax.security.auth.kerberos.ServicePermission=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
sun.security.jgss.GSSCaller=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
sun.security.jgss.krb5.Krb5Util=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
sun.security.jgss.krb5.ServiceCreds=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.EncryptedData= sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.EncryptionKey=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.internal.crypto.KeyUsage=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.internal.EncTicketPart=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.internal.Krb5=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.internal.Ticket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.KrbException=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.PrincipalName=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
sun.security.krb5.Realm=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
# Residual references to java.beans.
# The RemoveMethods tool does not yet purge the constant pool.
#
java.beans.PropertyChangeListener=java.util.logging.LogManager,compact1,compact2,compact3

View file

@ -28,6 +28,13 @@
# string and the runtime name into the Version.java file. # string and the runtime name into the Version.java file.
# To be printed by java -version # To be printed by java -version
# These dependencies should ideally be added to prerequesites for Version.java
# but skip for now until we have better incremental build for java.
# $(call DependOnVariable, LAUNCHER_NAME) \
# $(call DependOnVariable, RELEASE) \
# $(call DependOnVariable, FULL_VERSION) \
# $(call DependOnVariable, RUNTIME_VERSION)
$(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/misc/Version.java: \ $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/misc/Version.java: \
$(JDK_TOPDIR)/src/java.base/share/classes/sun/misc/Version.java.template $(JDK_TOPDIR)/src/java.base/share/classes/sun/misc/Version.java.template
$(MKDIR) -p $(@D) $(MKDIR) -p $(@D)

View file

@ -74,8 +74,6 @@ endif
########################################################################################## ##########################################################################################
BUILD_LIBVERIFY_SRC := check_code.c check_format.c
ifeq ($(OPENJDK_TARGET_OS), solaris) ifeq ($(OPENJDK_TARGET_OS), solaris)
ifneq ($(OPENJDK_TARGET_CPU), x86_64) ifneq ($(OPENJDK_TARGET_CPU), x86_64)
BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/make/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU) BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/make/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU)
@ -116,10 +114,6 @@ TARGETS += $(BUILD_LIBVERIFY)
LIBJAVA_SRC_DIRS := $(call FindSrcDirsForLib, java.base, java) LIBJAVA_SRC_DIRS := $(call FindSrcDirsForLib, java.base, java)
ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBJAVA_EXCLUDE_FILES += $(JDK_TOPDIR)/src/java.base/unix/native/libjava/HostLocaleProviderAdapter_md.c
endif
LIBJAVA_CFLAGS := $(addprefix -I, $(LIBJAVA_SRC_DIRS)) \ LIBJAVA_CFLAGS := $(addprefix -I, $(LIBJAVA_SRC_DIRS)) \
-I$(JDK_TOPDIR)/src/java.base/share/native/libfdlibm \ -I$(JDK_TOPDIR)/src/java.base/share/native/libfdlibm \
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \ -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
@ -134,9 +128,7 @@ ifneq (, $(JDK_UPDATE_VERSION))
LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"' LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"'
endif endif
ifneq ($(OPENJDK_TARGET_OS), macosx) ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBJAVA_EXCLUDE_FILES += java_props_macosx.c
else
BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c
BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c
endif endif
@ -151,8 +143,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
LIBRARY := java, \ LIBRARY := java, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAVA_SRC_DIRS), \ SRC := $(LIBJAVA_SRC_DIRS), \
EXCLUDES := fdlibm/src zip prefs, \
EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \
LANG := C, \ LANG := C, \
OPTIMIZATION := HIGH, \ OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) \ CFLAGS := $(CFLAGS_JDKLIB) \
@ -247,19 +237,10 @@ TARGETS += $(BUILD_LIBZIP)
########################################################################################## ##########################################################################################
BUILD_LIBJLI_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libjli \ LIBJLI_SRC_DIRS := $(call FindSrcDirsForLib, java.base, jli)
$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli
LIBJLI_CFLAGS := $(CFLAGS_JDKLIB) LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
BUILD_LIBJLI_FILES := \
java.c \
splashscreen_stubs.c \
parse_manifest.c \
version_comp.c \
wildcard.c \
jli_util.c
ifeq ($(JVM_VARIANT_ZERO), true) ifeq ($(JVM_VARIANT_ZERO), true)
ERGO_FAMILY := zero ERGO_FAMILY := zero
else else
@ -269,68 +250,55 @@ else
ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH) ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH)
endif endif
endif endif
LIBJLI_ALL_ERGO := $(wildcard $(addsuffix /ergo_*.c, $(LIBJLI_SRC_DIRS)))
LIBJLI_EXCLUDE_ERGO := $(filter-out %/ergo_$(ERGO_FAMILY).c, $(LIBJLI_ALL_ERGO))
# If all specialized ergo files are excluded, use generic ergo
ifeq ($(LIBJLI_ALL_ERGO), $(LIBJLI_EXCLUDE_ERGO))
LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO
endif
LIBJLI_EXCLUDE_FILES += $(notdir $(LIBJLI_EXCLUDE_ERGO))
ifeq ($(OPENJDK_TARGET_OS), macosx) ifeq ($(OPENJDK_TARGET_OS), macosx)
BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/macosx/native/libjli LIBJLI_EXCLUDE_FILES += java_md_solinux.c ergo.c
BUILD_LIBJLI_FILES += java_md_common.c java_md_macosx.c
BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c
BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c
endif
ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_LIBJLI_FILES += java_md.c \
cmdtoargs.c
# Staticically link with c runtime on windows.
LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS))
else ifneq ($(OPENJDK_TARGET_OS), macosx)
BUILD_LIBJLI_FILES += java_md_common.c
BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c
ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c
# if the architecture specific ergo file exists then
# use it, else use the generic definitions from ergo.c
ifneq ($(wildcard $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli/$(ERGO_ARCH_FILE)), )
BUILD_LIBJLI_FILES += $(ERGO_ARCH_FILE)
else # !ERGO_ARCH_FILE
LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO
endif # ERGO_ARCH_FILE
endif #WINDOWS
LIBJLI_CFLAGS += $(foreach dir, $(BUILD_LIBJLI_SRC_DIRS), -I$(dir))
# Append defines depending on target platform
LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\"
endif endif
ifneq ($(USE_EXTERNAL_LIBZ), true)
BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8
LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
BUILD_LIBJLI_FILES += \
inflate.c \
inftrees.c \
inffast.c \
zadler32.c \
zcrc32.c \
zutil.c
endif
ifeq ($(OPENJDK_TARGET_OS), windows) ifeq ($(OPENJDK_TARGET_OS), windows)
# Staticically link with c runtime on windows.
LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS))
LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE) LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)
else else
LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli
endif endif
LIBJLI_CFLAGS += $(addprefix -I, $(LIBJLI_SRC_DIRS))
# Append defines depending on target platform
LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
ifneq ($(USE_EXTERNAL_LIBZ), true)
LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
LIBJLI_EXTRA_FILES += \
$(addprefix $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8/, \
inflate.c \
inftrees.c \
inffast.c \
zadler32.c \
zcrc32.c \
zutil.c \
)
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
LIBRARY := jli, \ LIBRARY := jli, \
OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \ OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \
SRC := $(BUILD_LIBJLI_SRC_DIRS), \ SRC := $(LIBJLI_SRC_DIRS), \
INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
LANG := C, \ LANG := C, \
OPTIMIZATION := HIGH, \ OPTIMIZATION := HIGH, \
CFLAGS := $(LIBJLI_CFLAGS), \ CFLAGS := $(LIBJLI_CFLAGS), \
@ -376,8 +344,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
STATIC_LIBRARY := jli_static, \ STATIC_LIBRARY := jli_static, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(BUILD_LIBJLI_SRC_DIRS), \ SRC := $(LIBJLI_SRC_DIRS), \
INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
LANG := C, \ LANG := C, \
OPTIMIZATION := HIGH, \ OPTIMIZATION := HIGH, \
CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \ CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
@ -395,8 +364,9 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
LIBRARY := jli_static, \ LIBRARY := jli_static, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(BUILD_LIBJLI_SRC_DIRS), \ SRC := $(LIBJLI_SRC_DIRS), \
INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
LANG := C, \ LANG := C, \
OPTIMIZATION := HIGH, \ OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \ CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \
@ -411,16 +381,17 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
else ifeq ($(OPENJDK_TARGET_OS), aix) else ifeq ($(OPENJDK_TARGET_OS), aix)
# AIX also requires a static libjli because the compiler doesn't support '-rpath' # AIX also requires a static libjli because the compiler doesn't support '-rpath'
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC,\ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
STATIC_LIBRARY:=jli_static,\ STATIC_LIBRARY := jli_static, \
OUTPUT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE),\ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC:=$(BUILD_LIBJLI_SRC_DIRS),\ SRC := $(LIBJLI_SRC_DIRS), \
INCLUDE_FILES:=$(BUILD_LIBJLI_FILES),\ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
LANG:=C,\ EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
OPTIMIZATION:=HIGH, \ LANG := C, \
CFLAGS:=$(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS),\ OPTIMIZATION := HIGH, \
ARFLAGS:=$(ARFLAGS),\ CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
OBJECT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static)) ARFLAGS := $(ARFLAGS), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static))
TARGETS += $(BUILD_LIBJLI_STATIC) TARGETS += $(BUILD_LIBJLI_STATIC)

View file

@ -31,7 +31,7 @@ include LibCommon.gmk
$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
LIBRARY := attach, \ LIBRARY := attach, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(JDK_TOPDIR)/src/jdk.attach/$(OPENJDK_TARGET_OS)/native/libattach, \ SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
LANG := C, \ LANG := C, \
OPTIMIZATION := LOW, \ OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \ CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \

View file

@ -28,9 +28,7 @@ include LibCommon.gmk
################################################################################ ################################################################################
LIBJAAS_MAPFILE := LIBJAAS_MAPFILE :=
ifneq ($(OPENJDK_TARGET_OS), solaris) ifeq ($(OPENJDK_TARGET_OS), solaris)
LIBJAAS_EXCLUDE_FILES := Solaris.c
else
# only on solaris...wonder why # only on solaris...wonder why
LIBJAAS_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjaas/mapfile-vers LIBJAAS_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjaas/mapfile-vers
endif endif
@ -43,7 +41,7 @@ endif
$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \ $(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
LIBRARY := $(LIBJAAS_NAME), \ LIBRARY := $(LIBJAAS_NAME), \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(JDK_TOPDIR)/src/jdk.security.auth/$(OPENJDK_TARGET_OS_TYPE)/native/libjaas, \ SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \
LANG := C, \ LANG := C, \
OPTIMIZATION := LOW, \ OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \
@ -53,7 +51,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \ LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \
LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \ LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \
LDFLAGS_SUFFIX_solaris := -lc, \ LDFLAGS_SUFFIX_solaris := -lc, \
EXCLUDE_FILES := $(LIBJAAS_EXCLUDE_FILES), \
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
RC_FLAGS := $(RC_FLAGS) \ RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=$(LIBJAAS_NAME).dll" \ -D "JDK_FNAME=$(LIBJAAS_NAME).dll" \

View file

@ -23,39 +23,16 @@
# questions. # questions.
# #
LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libnet \ LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net)
$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnet
LIBNET_CFLAGS += -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
$(LIBJAVA_HEADER_FLAGS)
LIBNET_CFLAGS += $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir))
LIBNET_EXCLUDE_FILES :=
ifneq ($(OPENJDK_TARGET_OS), solaris)
LIBNET_EXCLUDE_FILES += solaris_close.c
endif
ifneq ($(OPENJDK_TARGET_OS), linux)
LIBNET_EXCLUDE_FILES += linux_close.c
endif
ifneq ($(OPENJDK_TARGET_OS), macosx)
LIBNET_EXCLUDE_FILES += bsd_close.c
endif
ifeq ($(OPENJDK_TARGET_OS), aix)
LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnet/java/net/
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \ $(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
LIBRARY := net, \ LIBRARY := net, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBNET_SRC_DIRS), \ SRC := $(LIBNET_SRC_DIRS), \
EXCLUDE_FILES := $(LIBNET_EXCLUDE_FILES), \
LANG := C, \ LANG := C, \
OPTIMIZATION := LOW, \ OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
$(LIBNET_CFLAGS), \ $(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libnet/mapfile-vers, \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libnet/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \ LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \ $(call SET_SHARED_LIBRARY_ORIGIN), \

View file

@ -65,7 +65,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(BUILD_LIBNIO_SRC), \ SRC := $(BUILD_LIBNIO_SRC), \
EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \ EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
EXCLUDES := sctp, \
LANG := C, \ LANG := C, \
OPTIMIZATION := HIGH, \ OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) \ CFLAGS := $(CFLAGS_JDKLIB) \

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -214,10 +214,10 @@ SUNWprivate_1.1 {
Java_java_lang_Throwable_fillInStackTrace; Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth; Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement; Java_java_lang_Throwable_getStackTraceElement;
Java_java_lang_UNIXProcess_init; Java_java_lang_ProcessImpl_init;
Java_java_lang_UNIXProcess_waitForProcessExit; Java_java_lang_ProcessImpl_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec; Java_java_lang_ProcessImpl_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess; Java_java_lang_ProcessImpl_destroyProcess;
Java_java_nio_Bits_copyFromShortArray; Java_java_nio_Bits_copyFromShortArray;
Java_java_nio_Bits_copyToShortArray; Java_java_nio_Bits_copyToShortArray;
Java_java_nio_Bits_copyFromIntArray; Java_java_nio_Bits_copyFromIntArray;

View file

@ -1,226 +0,0 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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.deps;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Dependencies;
import com.sun.tools.classfile.Dependency;
/**
* A simple tool to check the JAR files in a JRE image to ensure that there
* aren't any references to types that do not exist. The tool is intended to
* be used in the JDK "profiles" build to help ensure that the profile
* definitions are kept up to date.
*/
public class CheckDeps {
// classfile API for finding dependencies
static final Dependency.Finder finder = Dependencies.getClassDependencyFinder();
// "known types", found in rt.jar or other JAR files
static final Set<String> knownTypes = new HashSet<>();
// References to unknown types. The map key is the unknown type, the
// map value is the set of classes that reference it.
static final Map<String,Set<String>> unknownRefs = new HashMap<>();
// The property name is the name of an unknown type that is allowed to be
// references. The property value is a comma separated list of the types
// that are allowed to reference it. The list also includes the names of
// the profiles that the reference is allowed.
static final Properties allowedBadRefs = new Properties();
/**
* Returns the class name for the given class file. In the case of inner
* classes then the enclosing class is returned in order to keep the
* rules simple.
*/
static String toClassName(String s) {
int i = s.indexOf('$');
if (i > 0)
s = s.substring(0, i);
return s.replace("/", ".");
}
/**
* Analyze the dependencies of all classes in the given JAR file. The
* method updates knownTypes and unknownRefs as part of the analysis.
*/
static void analyzeDependencies(Path jarpath) throws Exception {
System.out.format("Analyzing %s%n", jarpath);
try (JarFile jf = new JarFile(jarpath.toFile())) {
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry e = entries.nextElement();
String name = e.getName();
if (name.endsWith(".class")) {
ClassFile cf = ClassFile.read(jf.getInputStream(e));
for (Dependency d : finder.findDependencies(cf)) {
String origin = toClassName(d.getOrigin().getName());
String target = toClassName(d.getTarget().getName());
// origin is now known
unknownRefs.remove(origin);
knownTypes.add(origin);
// if the target is not known then record the reference
if (!knownTypes.contains(target)) {
Set<String> refs = unknownRefs.get(target);
if (refs == null) {
// first time seeing this unknown type
refs = new HashSet<>();
unknownRefs.put(target, refs);
}
refs.add(origin);
}
}
}
}
}
}
/**
* We have closure (no references to types that do not exist) if
* unknownRefs is empty. When unknownRefs is not empty then it should
* only contain references that are allowed to be present (these are
* loaded from the refs.allowed properties file).
*
* @param the profile that is being tested, this determines the exceptions
* in {@code allowedBadRefs} that apply.
*
* @return {@code true} if there are no missing types or the only references
* to missing types are described by {@code allowedBadRefs}.
*/
static boolean checkClosure(String profile) {
// process the references to types that do not exist.
boolean fail = false;
for (Map.Entry<String,Set<String>> entry: unknownRefs.entrySet()) {
String target = entry.getKey();
for (String origin: entry.getValue()) {
// check if origin -> target allowed
String value = allowedBadRefs.getProperty(target);
if (value == null) {
System.err.format("%s -> %s (unknown type)%n", origin, target);
fail = true;
} else {
// target is known, check if the origin is one that we
// expect and that the exception applies to the profile.
boolean found = false;
boolean applicable = false;
for (String s: value.split(",")) {
s = s.trim();
if (s.equals(origin))
found = true;
if (s.equals(profile))
applicable = true;
}
if (!found || !applicable) {
if (!found) {
System.err.format("%s -> %s (not allowed)%n", origin, target);
} else {
System.err.format("%s -> %s (reference not applicable to %s)%n",
origin, target, profile);
}
fail = true;
}
}
}
}
return !fail;
}
static void fail(URL url) throws Exception {
System.err.println("One or more unexpected references encountered");
if (url != null)
System.err.format("Check %s is up to date%n", Paths.get(url.toURI()));
System.exit(-1);
}
public static void main(String[] args) throws Exception {
// load properties file so that we know what missing types that are
// allowed to be referenced.
URL url = CheckDeps.class.getResource("refs.allowed");
if (url != null) {
try (InputStream in = url.openStream()) {
allowedBadRefs.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
}
if (args.length != 2) {
System.err.println("Usage: java CheckDeps <image> <profile>");
System.exit(-1);
}
String image = args[0];
String profile = args[1];
// process JAR files on boot class path
Path lib = Paths.get(image, "lib");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib, "*.jar")) {
for (Path jarpath: stream) {
analyzeDependencies(jarpath);
}
}
// classes on boot class path should not reference other types
boolean okay = checkClosure(profile);
if (!okay)
fail(url);
// process JAR files in the extensions directory
try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib.resolve("ext"), "*.jar")) {
for (Path jarpath: stream) {
analyzeDependencies(jarpath);
}
}
// re-check to ensure that the extensions doesn't reference types that
// do not exist.
okay = checkClosure(profile);
if (!okay)
fail(url);
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,9 @@ package java.lang;
import sun.misc.FloatingDecimal; import sun.misc.FloatingDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.Spliterator;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
/** /**
* A mutable sequence of characters. * A mutable sequence of characters.
@ -292,7 +295,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) { if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex); return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
} }
/** /**
@ -1431,6 +1434,34 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
@Override @Override
public abstract String toString(); public abstract String toString();
/**
* {@inheritDoc}
* @since 1.9
*/
@Override
public IntStream chars() {
// Reuse String-based spliterator. This requires a supplier to
// capture the value and count when the terminal operation is executed
return StreamSupport.intStream(
() -> new String.IntCharArraySpliterator(value, 0, count, 0),
Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
false);
}
/**
* {@inheritDoc}
* @since 1.9
*/
@Override
public IntStream codePoints() {
// Reuse String-based spliterator. This requires a supplier to
// capture the value and count when the terminal operation is executed
return StreamSupport.intStream(
() -> new String.CodePointsSpliterator(value, 0, count, 0),
Spliterator.ORDERED,
false);
}
/** /**
* Needed by {@code String} for the contentEquals method. * Needed by {@code String} for the contentEquals method.
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,6 +41,11 @@ public class Object {
registerNatives(); registerNatives();
} }
/**
* Constructs a new object.
*/
public Object() {}
/** /**
* Returns the runtime class of this {@code Object}. The returned * Returns the runtime class of this {@code Object}. The returned
* {@code Class} object is the object that is locked by {@code * {@code Class} object is the object that is locked by {@code
@ -86,12 +91,11 @@ public class Object {
* for unequal objects may improve the performance of hash tables. * for unequal objects may improve the performance of hash tables.
* </ul> * </ul>
* <p> * <p>
* As much as is reasonably practical, the hashCode method defined by * As much as is reasonably practical, the hashCode method defined
* class {@code Object} does return distinct integers for distinct * by class {@code Object} does return distinct integers for
* objects. (This is typically implemented by converting the internal * distinct objects. (The hashCode may or may not be implemented
* address of the object into an integer, but this implementation * as some function of an object's memory address at some point
* technique is not required by the * in time.)
* Java&trade; programming language.)
* *
* @return a hash code value for this object. * @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object) * @see java.lang.Object#equals(java.lang.Object)
@ -344,10 +348,12 @@ public class Object {
* ... // Perform action appropriate to condition * ... // Perform action appropriate to condition
* } * }
* </pre> * </pre>
* (For more information on this topic, see Section 3.2.3 in Doug Lea's *
* "Concurrent Programming in Java (Second Edition)" (Addison-Wesley, * (For more information on this topic, see section 14.2,
* 2000), or Item 50 in Joshua Bloch's "Effective Java Programming * Condition Queues, in Brian Goetz and others' "Java Concurrency
* Language Guide" (Addison-Wesley, 2001). * in Practice" (Addison-Wesley, 2006) or Item 69 in Joshua
* Bloch's "Effective Java (Second Edition)" (Addison-Wesley,
* 2008).
* *
* <p>If the current thread is {@linkplain java.lang.Thread#interrupt() * <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
* interrupted} by any thread before or while it is waiting, then an * interrupted} by any thread before or while it is waiting, then an

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,10 +34,14 @@ import java.util.Comparator;
import java.util.Formatter; import java.util.Formatter;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.Spliterator;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.function.IntConsumer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
/** /**
* The {@code String} class represents character strings. All * The {@code String} class represents character strings. All
@ -2894,6 +2898,180 @@ public final class String
return this; return this;
} }
static class IntCharArraySpliterator implements Spliterator.OfInt {
private final char[] array;
private int index; // current index, modified on advance/split
private final int fence; // one past last index
private final int cs;
IntCharArraySpliterator(char[] array, int acs) {
this(array, 0, array.length, acs);
}
IntCharArraySpliterator(char[] array, int origin, int fence, int acs) {
this.array = array;
this.index = origin;
this.fence = fence;
this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
| Spliterator.SUBSIZED;
}
@Override
public OfInt trySplit() {
int lo = index, mid = (lo + fence) >>> 1;
return (lo >= mid)
? null
: new IntCharArraySpliterator(array, lo, index = mid, cs);
}
@Override
public void forEachRemaining(IntConsumer action) {
char[] a; int i, hi; // hoist accesses and checks from loop
if (action == null)
throw new NullPointerException();
if ((a = array).length >= (hi = fence) &&
(i = index) >= 0 && i < (index = hi)) {
do { action.accept(a[i]); } while (++i < hi);
}
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (action == null)
throw new NullPointerException();
if (index >= 0 && index < fence) {
action.accept(array[index++]);
return true;
}
return false;
}
@Override
public long estimateSize() { return (long)(fence - index); }
@Override
public int characteristics() {
return cs;
}
}
/**
* Returns a stream of {@code int} zero-extending the {@code char} values
* from this sequence. Any char which maps to a <a
* href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
* point</a> is passed through uninterpreted.
*
* @return an IntStream of char values from this sequence
* @since 1.9
*/
@Override
public IntStream chars() {
return StreamSupport.intStream(
new IntCharArraySpliterator(value, Spliterator.IMMUTABLE), false);
}
static class CodePointsSpliterator implements Spliterator.OfInt {
private final char[] array;
private int index; // current index, modified on advance/split
private final int fence; // one past last index
private final int cs;
CodePointsSpliterator(char[] array, int acs) {
this(array, 0, array.length, acs);
}
CodePointsSpliterator(char[] array, int origin, int fence, int acs) {
this.array = array;
this.index = origin;
this.fence = fence;
this.cs = acs | Spliterator.ORDERED;
}
@Override
public OfInt trySplit() {
int lo = index, mid = (lo + fence) >>> 1;
if (lo >= mid)
return null;
int midOneLess;
// If the mid-point intersects a surrogate pair
if (Character.isLowSurrogate(array[mid]) &&
Character.isHighSurrogate(array[midOneLess = (mid -1)])) {
// If there is only one pair it cannot be split
if (lo >= midOneLess)
return null;
// Shift the mid-point to align with the surrogate pair
return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
}
return new CodePointsSpliterator(array, lo, index = mid, cs);
}
@Override
public void forEachRemaining(IntConsumer action) {
char[] a; int i, hi; // hoist accesses and checks from loop
if (action == null)
throw new NullPointerException();
if ((a = array).length >= (hi = fence) &&
(i = index) >= 0 && i < (index = hi)) {
do {
i = advance(a, i, hi, action);
} while (i < hi);
}
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (action == null)
throw new NullPointerException();
if (index >= 0 && index < fence) {
index = advance(array, index, fence, action);
return true;
}
return false;
}
// Advance one code point from the index, i, and return the next
// index to advance from
private static int advance(char[] a, int i, int hi, IntConsumer action) {
char c1 = a[i++];
int cp = c1;
if (Character.isHighSurrogate(c1) && i < hi) {
char c2 = a[i];
if (Character.isLowSurrogate(c2)) {
i++;
cp = Character.toCodePoint(c1, c2);
}
}
action.accept(cp);
return i;
}
@Override
public long estimateSize() { return (long)(fence - index); }
@Override
public int characteristics() {
return cs;
}
}
/**
* Returns a stream of code point values from this sequence. Any surrogate
* pairs encountered in the sequence are combined as if by {@linkplain
* Character#toCodePoint Character.toCodePoint} and the result is passed
* to the stream. Any other code units, including ordinary BMP characters,
* unpaired surrogates, and undefined code units, are zero-extended to
* {@code int} values which are then passed to the stream.
*
* @return an IntStream of Unicode code points from this sequence
* @since 1.9
*/
@Override
public IntStream codePoints() {
return StreamSupport.intStream(
new CodePointsSpliterator(value, Spliterator.IMMUTABLE), false);
}
/** /**
* Converts this string to a new character array. * Converts this string to a new character array.
* *

View file

@ -376,19 +376,16 @@ public final class System {
* the difference between two such values, obtained within the same * the difference between two such values, obtained within the same
* instance of a Java virtual machine, is computed. * instance of a Java virtual machine, is computed.
* *
* <p> For example, to measure how long some code takes to execute: * <p>For example, to measure how long some code takes to execute:
* <pre> {@code * <pre> {@code
* long startTime = System.nanoTime(); * long startTime = System.nanoTime();
* // ... the code being measured ... * // ... the code being measured ...
* long estimatedTime = System.nanoTime() - startTime;}</pre> * long elapsedNanos = System.nanoTime() - startTime;}</pre>
* *
* <p>To compare two nanoTime values * <p>To compare elapsed time against a timeout, use <pre> {@code
* <pre> {@code * if (System.nanoTime() - startTime >= timeoutNanos) ...}</pre>
* long t0 = System.nanoTime(); * instead of <pre> {@code
* ... * if (System.nanoTime() >= startTime + timeoutNanos) ...}</pre>
* long t1 = System.nanoTime();}</pre>
*
* one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
* because of the possibility of numerical overflow. * because of the possibility of numerical overflow.
* *
* @return the current value of the running Java Virtual Machine's * @return the current value of the running Java Virtual Machine's

View file

@ -553,6 +553,12 @@ public interface Spliterator<T> {
* sub-split size is known and additions or removals to the source are not * sub-split size is known and additions or removals to the source are not
* reflected when traversing. * reflected when traversing.
* *
* <p>A top-level Spliterator should not report both {@code CONCURRENT} and
* {@code IMMUTABLE}, since they are mutually exclusive. Such a Spliterator
* is inconsistent and no guarantees can be made about any computation using
* that Spliterator. Sub-spliterators may report {@code IMMUTABLE} if
* additions or removals to the source are not reflected when traversing.
*
* @apiNote Most concurrent collections maintain a consistency policy * @apiNote Most concurrent collections maintain a consistency policy
* guaranteeing accuracy with respect to elements present at the point of * guaranteeing accuracy with respect to elements present at the point of
* Spliterator construction, but possibly not reflecting subsequent * Spliterator construction, but possibly not reflecting subsequent

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